Skip to content

Commit

Permalink
Merge NvPair-Fix into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
ja-fra committed Apr 25, 2024
2 parents 700b4ae + ae7e1c0 commit c92f9c9
Show file tree
Hide file tree
Showing 10 changed files with 231 additions and 78 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,35 +19,84 @@
@Component
public class NameValuePairRepository {

private static final String UPSERT = "INSERT INTO nvpairs(issuer,name,value) VALUES (?,?,?) ON CONFLICT(issuer,name) DO UPDATE SET value = EXCLUDED.value";
private static final String READ = "SELECT value FROM nvpairs WHERE issuer = ? AND name = ? LIMIT 1";
private static final String REMOVE = "DELETE FROM nvpairs WHERE issuer = ? AND name = ?";
private static final String UPSERT_O = "INSERT INTO nvpairs_observations(study_id, observation_id, name, value) VALUES (?,?,?,?) ON CONFLICT(study_id, observation_id, name) DO UPDATE SET value = EXCLUDED.value";
private static final String UPSERT_T = "INSERT INTO nvpairs_triggers(study_id, intervention_id, name, value) VALUES (?,?,?,?) ON CONFLICT(study_id, intervention_id, name) DO UPDATE SET value = EXCLUDED.value";
private static final String UPSERT_A = "INSERT INTO nvpairs_actions(study_id, intervention_id, action_id, name, value) VALUES (?,?,?,?,?) ON CONFLICT(study_id, intervention_id, action_id, name) DO UPDATE SET value = EXCLUDED.value";
private static final String READ_O = "SELECT value FROM nvpairs_observations WHERE study_id = ? AND observation_id = ? AND name = ? LIMIT 1";
private static final String READ_T = "SELECT value FROM nvpairs_triggers WHERE study_id = ? AND intervention_id = ? AND name = ? LIMIT 1";
private static final String READ_A = "SELECT value FROM nvpairs_actions WHERE study_id = ? AND intervention_id = ? AND action_id = ? AND name = ? LIMIT 1";
private static final String REMOVE_O = "DELETE FROM nvpairs_observations WHERE study_id = ? AND observation_id = ? AND name = ?";
private static final String REMOVE_T = "DELETE FROM nvpairs_triggers WHERE study_id = ? AND intervention_id = ? AND name = ?";
private static final String REMOVE_A = "DELETE FROM nvpairs_actions WHERE study_id = ? AND intervention_id = ? AND action_id = ? AND name = ?";

private final JdbcTemplate template;

public NameValuePairRepository(JdbcTemplate template) {
this.template = template;
}

public <T extends Serializable> void setValue(String issuer, String name, T value) {
this.template.update(UPSERT, issuer, name, SerializationUtils.serialize(value));
public <T extends Serializable> void setObservationValue(Long studyId, int observationId, String name, T value) {
this.template.update(UPSERT_O, studyId, observationId, name, SerializationUtils.serialize(value));
}

public <T extends Serializable> Optional<T> getValue(String issuer, String name, Class<T> tClass) {
public <T extends Serializable> void setTriggerValue(Long studyId, int interventionId, String name, T value) {
this.template.update(UPSERT_T, studyId, interventionId, name, SerializationUtils.serialize(value));
}

public <T extends Serializable> void setActionValue(Long studyId, int interventionId, int actionId, String name, T value) {
this.template.update(UPSERT_A, studyId, interventionId, actionId, name, SerializationUtils.serialize(value));
}

public <T extends Serializable> Optional<T> getObservationValue(Long studyId, int observationId, String name, Class<T> tClass) {
try {
return Optional.ofNullable(this.template.queryForObject(READ_O,
(rs, rowNum) -> tClass.cast(SerializationUtils.deserialize(rs.getBytes("value"))),
studyId, observationId, name));
} catch (EmptyResultDataAccessException e) {
return Optional.empty();
}
}

public <T extends Serializable> Optional<T> getTriggerValue(Long studyId, int interventionId, String name, Class<T> tClass) {
try {
return Optional.ofNullable(this.template.queryForObject(READ_T,
(rs, rowNum) -> tClass.cast(SerializationUtils.deserialize(rs.getBytes("value"))),
studyId, interventionId, name));
} catch (EmptyResultDataAccessException e) {
return Optional.empty();
}
}

public <T extends Serializable> Optional<T> getActionValue(Long studyId, int interventionId, int actionId, String name, Class<T> tClass) {
try {
return Optional.ofNullable(this.template.queryForObject(READ,
return Optional.ofNullable(this.template.queryForObject(READ_A,
(rs, rowNum) -> tClass.cast(SerializationUtils.deserialize(rs.getBytes("value"))),
issuer, name));
studyId, interventionId, actionId, name));
} catch (EmptyResultDataAccessException e) {
return Optional.empty();
}
}

public void removeValue(String issuer, String name) {
this.template.update(REMOVE, issuer, name);
public void removeObservationValue(Long studyId, int observationId, String name) {
this.template.update(REMOVE_O, studyId, observationId, name);
}

public void removeTriggerValue(Long studyId, int interventionId, String name) {
this.template.update(REMOVE_T, studyId, interventionId, name);
}

public void removeActionValue(Long studyId, int interventionId, int actionId, String name) {
this.template.update(REMOVE_A, studyId, interventionId, actionId, name);
}

protected boolean noObservationValues() {
return this.template.queryForObject(
"SELECT count(*) AS c FROM nvpairs_observations", Integer.class) == 0;
}

void clear() {
this.template.execute("DELETE FROM nvpairs");
this.template.execute("DELETE FROM nvpairs_observations");
this.template.execute("DELETE FROM nvpairs_triggers");
this.template.execute("DELETE FROM nvpairs_actions");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public class MoreSDK {

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

private final NameValuePairRepository nvpairs;
public final NameValuePairRepository nvpairs;

private final SchedulingService schedulingService;

Expand All @@ -69,18 +69,6 @@ public MoreSDK(
this.observationRepository = observationRepository;
}

public <T extends Serializable> void setValue(String issuer, String name, T value) {
nvpairs.setValue(issuer, name, value);
}

public <T extends Serializable> Optional<T> getValue(String issuer, String name, Class<T> tClass) {
return nvpairs.getValue(issuer, name, tClass);
}

public void removeValue(String issuer, String name) {
nvpairs.removeValue(issuer, name);
}

public MoreActionSDK scopedActionSDK(Long studyId, Integer studyGroupId, int interventionId, int actionId, String actionType, int participantId) {
return new MoreActionSDKImpl(this, studyId, studyGroupId, interventionId, actionId, actionType, participantId);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.Serializable;
import java.time.Instant;
import java.util.Map;
import java.util.Optional;

public class MoreActionSDKImpl extends MorePlatformSDKImpl implements MoreActionSDK {
private static final Logger LOGGER = LoggerFactory.getLogger(MoreActionSDKImpl.class);
Expand All @@ -34,6 +36,21 @@ public MoreActionSDKImpl(MoreSDK sdk, long studyId, Integer studyGroupId, int in
this.participantId = participantId;
}

@Override
public <T extends Serializable> void setValue(String name, T value) {
sdk.nvpairs.setActionValue(studyId, interventionId, actionId, name, value);
}

@Override
public <T extends Serializable> Optional<T> getValue(String name, Class<T> tClass) {
return sdk.nvpairs.getActionValue(studyId, interventionId, actionId, name, tClass);
}

@Override
public void removeValue(String name) {
sdk.nvpairs.removeActionValue(studyId, interventionId, actionId, name);
}

@Override
public void sendPushNotification(String title, String message) {
try (var ctx = LoggingUtils.createContext()) {
Expand Down Expand Up @@ -68,9 +85,4 @@ public void triggerObservation(String title, String message, String factoryId, i
}
}
}

@Override
public String getIssuer() {
return studyId + "-" + studyGroupId + '-' + interventionId + "-" + actionId + "-action";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import io.redlink.more.studymanager.model.data.ElasticDataPoint;
import io.redlink.more.studymanager.sdk.MoreSDK;

import java.io.Serializable;
import java.time.Instant;
import java.util.Map;
import java.util.Optional;
Expand All @@ -27,8 +28,18 @@ public MoreObservationSDKImpl(MoreSDK sdk, long studyId, Integer studyGroupId, i
}

@Override
public String getIssuer() {
return studyId + "-" + studyGroupId + '-' + observationId + "-observation";
public <T extends Serializable> void setValue(String name, T value) {
sdk.nvpairs.setObservationValue(studyId, observationId, name, value);
}

@Override
public <T extends Serializable> Optional<T> getValue(String name, Class<T> tClass) {
return sdk.nvpairs.getObservationValue(studyId, observationId, name, tClass);
}

@Override
public void removeValue(String name) {
sdk.nvpairs.removeObservationValue(studyId, observationId, name);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@
import io.redlink.more.studymanager.model.Participant;
import io.redlink.more.studymanager.sdk.MoreSDK;

import java.io.Serializable;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -51,21 +49,4 @@ public Set<SimpleParticipant> participants(ParticipantFilter filter) {
(filter == ParticipantFilter.ACTIVE_ONLY ? Set.of(Participant.Status.ACTIVE) : null);
return sdk.listParticipants(studyId, studyGroupId, state);
}

@Override
public <T extends Serializable> void setValue(String name, T value) {
sdk.setValue(getIssuer(), name, value);
}

@Override
public <T extends Serializable> Optional<T> getValue(String name, Class<T> tClass) {
return sdk.getValue(getIssuer(), name, tClass);
}

@Override
public void removeValue(String name) {
sdk.removeValue(getIssuer(), name);
}

public abstract String getIssuer();
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
import io.redlink.more.studymanager.sdk.MoreSDK;
import org.apache.commons.lang3.NotImplementedException;

import java.io.Serializable;
import java.util.Optional;
import java.util.Set;

public class MoreTriggerSDKImpl extends MorePlatformSDKImpl implements MoreTriggerSDK {
Expand All @@ -25,6 +27,21 @@ public MoreTriggerSDKImpl(MoreSDK sdk, long studyId, Integer studyGroupId, int i
this.interventionId = interventionId;
}

@Override
public <T extends Serializable> void setValue(String name, T value) {
sdk.nvpairs.setTriggerValue(studyId, interventionId, name, value);
}

@Override
public <T extends Serializable> Optional<T> getValue(String name, Class<T> tClass) {
return sdk.nvpairs.getTriggerValue(studyId, interventionId, name, tClass);
}

@Override
public void removeValue(String name) {
sdk.nvpairs.removeTriggerValue(studyId, interventionId, name);
}

@Override
public String addSchedule(Schedule schedule) {
return sdk.addSchedule(getIssuer(), studyId, studyGroupId, interventionId, schedule);
Expand All @@ -49,8 +66,7 @@ public void removeWebhook() {
throw new NotImplementedException();
}

@Override
public String getIssuer() {
private String getIssuer() {
return studyId + "-" + studyGroupId + '-' + interventionId + "-trigger";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
CREATE TABLE IF NOT EXISTS nvpairs_observations (
study_id BIGINT NOT NULL,
observation_id INT,
name VARCHAR,
value bytea NOT NULL,

PRIMARY KEY (study_id, observation_id, name),
FOREIGN KEY (study_id, observation_id) REFERENCES observations(study_id, observation_id) ON DELETE CASCADE
);

WITH legacy AS (
SELECT
name,
value,
CAST(substring(issuer, '^\d+') AS BIGINT) AS study_id,
CAST(substring(replace(issuer, 'null', '0'), '^\d+-\d+-(\d+)') AS INT) AS observation_id
FROM nvpairs
WHERE issuer LIKE '%_observation'
)
INSERT INTO nvpairs_observations (name, value, study_id, observation_id)
SELECT legacy.* FROM legacy
INNER JOIN observations ON (legacy.study_id = observations.study_id AND legacy.observation_id = observations.observation_id)
ON CONFLICT DO NOTHING;

CREATE TABLE IF NOT EXISTS nvpairs_triggers (
study_id BIGINT NOT NULL,
intervention_id INT,
name VARCHAR,
value bytea NOT NULL,

PRIMARY KEY (study_id, intervention_id, name),
FOREIGN KEY (study_id, intervention_id) REFERENCES interventions(study_id, intervention_id) ON DELETE CASCADE,
FOREIGN KEY (study_id, intervention_id) REFERENCES triggers(study_id, intervention_id) ON DELETE CASCADE
);

WITH legacy AS (
SELECT
name,
value,
CAST(substring(issuer, '^\d+') AS BIGINT) AS study_id,
CAST(substring(replace(issuer, 'null', '0'), '^\d+-\d+-(\d+)') AS INT) AS intervention_id
FROM nvpairs
WHERE issuer LIKE '%_trigger'
)
INSERT INTO nvpairs_triggers (name, value, study_id, intervention_id)
SELECT legacy.* FROM legacy
INNER JOIN triggers ON (legacy.study_id = triggers.study_id AND legacy.intervention_id = triggers.intervention_id)
ON CONFLICT DO NOTHING;

CREATE TABLE IF NOT EXISTS nvpairs_actions (
study_id BIGINT NOT NULL,
intervention_id INT,
action_id INT,
name VARCHAR,
value bytea NOT NULL,

PRIMARY KEY (study_id, intervention_id, action_id, name),
FOREIGN KEY (study_id, intervention_id) REFERENCES interventions(study_id, intervention_id) ON DELETE CASCADE,
FOREIGN KEY (study_id, intervention_id, action_id) REFERENCES actions(study_id, intervention_id, action_id) ON DELETE CASCADE
);

WITH legacy AS (
SELECT
name,
value,
CAST(substring(issuer, '^\d+') AS BIGINT) AS study_id,
CAST(substring(replace(issuer, 'null', '0'), '^\d+-\d+-(\d+)') AS INT) AS intervention_id,
CAST(substring(replace(issuer, 'null', '0'), '^\d+-\d+-\d+-(\d+)') AS INT) AS action_id
FROM nvpairs
WHERE issuer LIKE '%_action'
)
INSERT INTO nvpairs_actions (name, value, study_id, intervention_id, action_id)
SELECT legacy.* FROM legacy
INNER JOIN actions ON (legacy.study_id = actions.study_id AND legacy.intervention_id = actions.intervention_id AND legacy.action_id = actions.action_id)
ON CONFLICT DO NOTHING;

DROP TABLE nvpairs;
Loading

0 comments on commit c92f9c9

Please sign in to comment.