Skip to content

Commit

Permalink
Bugfix/939 clob getall office filter (#1024)
Browse files Browse the repository at this point in the history
I'm redoing pr #937 to address #939.  

develop had moved significantly since #937 had been started that it
seemed cleaner to just grab the handful of changes.

---------

Co-authored-by: ryan <[email protected]>
  • Loading branch information
rma-rripken and ryan authored Feb 18, 2025
1 parent aac98d7 commit c224cc5
Show file tree
Hide file tree
Showing 8 changed files with 179 additions and 190 deletions.
4 changes: 0 additions & 4 deletions cwms-data-api/src/main/java/cwms/cda/data/dao/AuthDao.java
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,6 @@ public static AuthDao getInstance(DSLContext dsl) {
return getInstance(dsl, null);
}

@Override
public List<DataApiPrincipal> getAll(String limitToOffice) {
throw new UnsupportedOperationException("Unimplemented method 'getAll'");
}

/**
* Reserved for future use, get user principal by presented unique name and office.
Expand Down
29 changes: 1 addition & 28 deletions cwms-data-api/src/main/java/cwms/cda/data/dao/BlobDao.java
Original file line number Diff line number Diff line change
Expand Up @@ -110,38 +110,11 @@ private static void handleResultSet(ResultSet resultSet, BlobConsumer consumer)
consumer.accept(blob, mediaType);
}


@Override
public List<Blob> getAll(String officeId) {
String queryStr = "SELECT AT_BLOB.ID, AT_BLOB.DESCRIPTION, CWMS_MEDIA_TYPE.MEDIA_TYPE_ID, CWMS_OFFICE.OFFICE_ID\n"
+ " FROM CWMS_20.AT_BLOB \n"
+ "join CWMS_20.CWMS_MEDIA_TYPE on AT_BLOB.MEDIA_TYPE_CODE = CWMS_MEDIA_TYPE.MEDIA_TYPE_CODE \n"
+ "join CWMS_20.CWMS_OFFICE on AT_BLOB.OFFICE_CODE=CWMS_OFFICE.OFFICE_CODE \n"
;

ResultQuery<Record> query;
if (officeId != null) {
queryStr = queryStr + " and upper(CWMS_OFFICE.OFFICE_ID) = upper(?)";
query = dsl.resultQuery(queryStr, officeId);
} else {
query = dsl.resultQuery(queryStr);
}

return query.fetch(r -> {
String rId = r.get("ID", String.class);
String rOffice = r.get("OFFICE_ID", String.class);
String rDesc = r.get("DESCRIPTION", String.class);
String rMedia = r.get("MEDIA_TYPE_ID", String.class);

return new Blob(rOffice, rId, rDesc, rMedia, null);
});
}

public List<Blob> getAll(String officeId, String like) {
String queryStr = "SELECT AT_BLOB.ID, AT_BLOB.DESCRIPTION, CWMS_MEDIA_TYPE.MEDIA_TYPE_ID, CWMS_OFFICE.OFFICE_ID\n"
+ " FROM CWMS_20.AT_BLOB \n"
+ "join CWMS_20.CWMS_MEDIA_TYPE on AT_BLOB.MEDIA_TYPE_CODE = CWMS_MEDIA_TYPE.MEDIA_TYPE_CODE \n"
+ "join CWMS_20.CWMS_OFFICE on AT_BLOB.OFFICE_CODE=CWMS_OFFICE.OFFICE_CODE \n"
+ "join CWMS_20.CWMS_OFFICE on AT_BLOB.OFFICE_CODE = CWMS_OFFICE.OFFICE_CODE \n"
+ " where REGEXP_LIKE (upper(AT_BLOB.ID), upper(?))"
;

Expand Down
165 changes: 66 additions & 99 deletions cwms-data-api/src/main/java/cwms/cda/data/dao/ClobDao.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,74 +42,48 @@ public ClobDao(DSLContext dsl) {
super(dsl);
}


// Yikes, I hate this method - it retrieves all the clobs? That could be gigabytes of data.
// Not returning Value or Desc fields until a useful way of working with this method is
// figured out.
@Override
public List<Clob> getAll(String limitToOffice) {
AV_CLOB ac = AV_CLOB.AV_CLOB;
AV_OFFICE ao = AV_OFFICE.AV_OFFICE;

Condition whereCond = noCondition();
if (limitToOffice != null && !limitToOffice.isEmpty()) {
whereCond = ao.OFFICE_ID.eq(limitToOffice);
}

return dsl.select(ac.ID, ao.OFFICE_ID)
.from(ac.join(ao).on(ac.OFFICE_CODE.eq(ao.OFFICE_CODE)))
.where(whereCond)
.fetch(joinRecord ->
new Clob(joinRecord.get(ao.OFFICE_ID),
joinRecord.get(ac.ID), null, null));

}

@Override
public Optional<Clob> getByUniqueName(String uniqueName, String office) {
AV_CLOB ac = AV_CLOB.AV_CLOB;
AV_OFFICE ao = AV_OFFICE.AV_OFFICE;
AV_CLOB vClob = AV_CLOB.AV_CLOB;
AV_OFFICE vOffice = AV_OFFICE.AV_OFFICE;

Condition cond = ac.ID.eq(uniqueName);
Condition cond = vClob.ID.eq(uniqueName);
if (office != null && !office.isEmpty()) {
cond = cond.and(ao.OFFICE_ID.eq(office));
cond = cond.and(vOffice.OFFICE_ID.eq(office));
}

RecordMapper<Record, Clob> mapper = joinRecord ->
new Clob(joinRecord.getValue(ao.OFFICE_ID),
joinRecord.getValue(ac.ID),
joinRecord.getValue(ac.DESCRIPTION),
joinRecord.getValue(ac.VALUE)
new Clob(joinRecord.getValue(vOffice.OFFICE_ID),
joinRecord.getValue(vClob.ID),
joinRecord.getValue(vClob.DESCRIPTION),
joinRecord.getValue(vClob.VALUE)
);

return dsl.select(ao.OFFICE_ID, ac.asterisk())
.from(ac.join(ao).on(ac.OFFICE_CODE.eq(ao.OFFICE_CODE)))
return dsl.select(vOffice.OFFICE_ID, vClob.asterisk())
.from(vClob.join(vOffice).on(vClob.OFFICE_CODE.eq(vOffice.OFFICE_CODE)))
.where(cond)
.fetchOptional(mapper);
}

public Clobs getClobs(String cursor, int pageSize, String officeLike,
boolean includeValues) {
return getClobs(cursor, pageSize, officeLike, includeValues, ".*");
}

public Clobs getClobs(String cursor, int pageSize, String officeLike,
boolean includeValues, String idRegex) {
int total = 0;
String clobCursor = "*";
AV_CLOB v_clob = AV_CLOB.AV_CLOB;
AV_OFFICE v_office = AV_OFFICE.AV_OFFICE;
String cursorOffice = null;
String cursorClobId = null;
AV_CLOB vClob = AV_CLOB.AV_CLOB;
AV_OFFICE vOffice = AV_OFFICE.AV_OFFICE;

Condition whereClause = JooqDao.caseInsensitiveLikeRegex(vClob.ID, idRegex)
.and(JooqDao.caseInsensitiveLikeRegexNullTrue(vOffice.OFFICE_ID, officeLike));
if (cursor == null || cursor.isEmpty()) {

SelectConditionStep<Record1<Integer>> count =
dsl.select(count(asterisk()))
.from(v_clob)
.join(v_office).on(v_clob.OFFICE_CODE.eq(v_office.OFFICE_CODE))
.where(JooqDao.caseInsensitiveLikeRegex(v_clob.ID, idRegex))
.and(officeLike == null ? noCondition() : DSL.upper(v_office.OFFICE_ID).like(officeLike.toUpperCase()));

total = count.fetchOne().value1();
SelectConditionStep<Record1<Integer>> count = dsl.select(count(asterisk()))
.from(vClob)
.join(vOffice).on(vClob.OFFICE_CODE.eq(vOffice.OFFICE_CODE))
.where(whereClause);
Record1<Integer> rec = count.fetchOne();
if(rec != null) {
total = rec.value1();
}
} else {
final String[] parts = CwmsDTOPaginated.decodeCursor(cursor, "||");

Expand All @@ -119,35 +93,41 @@ public Clobs getClobs(String cursor, int pageSize, String officeLike,
}

if (parts.length > 1) {
clobCursor = parts[0].split(";")[0];
clobCursor = clobCursor.substring(clobCursor.indexOf("/") + 1); // ditch the
// officeId that's embedded in
cursorOffice = Clobs.getOffice(cursor);
cursorClobId = Clobs.getId(cursor);
total = Integer.parseInt(parts[1]);
pageSize = Integer.parseInt(parts[2]);
}
}

Condition moreInSameOffice = cursorClobId == null || cursorOffice == null ? noCondition() :
vOffice.OFFICE_ID.eq(cursorOffice.toUpperCase())
.and(upper(vClob.ID).greaterThan(cursorClobId.toUpperCase()));
Condition nextOffices = cursorOffice == null ? noCondition():
upper(vOffice.OFFICE_ID).greaterThan(cursorOffice.toUpperCase());
Condition pagingCondition = moreInSameOffice.or(nextOffices);

SelectLimitPercentStep<Record4<String, String, String, String>> query = dsl.select(
v_office.OFFICE_ID,
v_clob.ID,
v_clob.DESCRIPTION,
includeValues ? v_clob.VALUE : DSL.inline("").as(v_clob.VALUE)
)
.from(v_clob)
//.innerJoin(forLimit).on(forLimit.field(v_clob.ID).eq(v_clob.ID))
.join(v_office).on(v_clob.OFFICE_CODE.eq(v_office.OFFICE_CODE))
.where(JooqDao.caseInsensitiveLikeRegex(v_clob.ID,idRegex))
.and(DSL.upper(v_clob.ID).greaterThan(clobCursor))
.orderBy(v_clob.ID).limit(pageSize);
vOffice.OFFICE_ID,
vClob.ID,
vClob.DESCRIPTION,
includeValues ? vClob.VALUE : DSL.inline("").as(vClob.VALUE)
)
.from(vClob)
.join(vOffice).on(vClob.OFFICE_CODE.eq(vOffice.OFFICE_CODE))
.where(whereClause)
.and(pagingCondition)
.orderBy(vOffice.OFFICE_ID, vClob.ID)
.limit(pageSize);


Clobs.Builder builder = new Clobs.Builder(clobCursor, pageSize, total);
Clobs.Builder builder = new Clobs.Builder(cursor, pageSize, total);

logger.atFine().log(query.getSQL(ParamType.INLINED));

query.fetch().forEach(row -> {
usace.cwms.db.jooq.codegen.tables.records.AV_CLOB clob = row.into(v_clob);
usace.cwms.db.jooq.codegen.tables.records.AV_OFFICE clobOffice = row.into(v_office);
usace.cwms.db.jooq.codegen.tables.records.AV_CLOB clob = row.into(vClob);
usace.cwms.db.jooq.codegen.tables.records.AV_OFFICE clobOffice = row.into(vOffice);
builder.addClob(new Clob(
clobOffice.getOFFICE_ID(),
clob.getID(),
Expand All @@ -162,35 +142,26 @@ public Clobs getClobs(String cursor, int pageSize, String officeLike,


public List<Clob> getClobsLike(String office, String idLike) {
AV_CLOB ac = AV_CLOB.AV_CLOB;
AV_OFFICE ao = AV_OFFICE.AV_OFFICE;
AV_CLOB vClob = AV_CLOB.AV_CLOB;
AV_OFFICE vOffice = AV_OFFICE.AV_OFFICE;

Condition cond = DSL.upper(ac.ID).like(idLike.toUpperCase());
Condition cond = DSL.upper(vClob.ID).like(idLike.toUpperCase());
if (office != null && !office.isEmpty()) {
cond = cond.and(DSL.upper(ao.OFFICE_ID).eq(office.toUpperCase()));
cond = cond.and(DSL.upper(vOffice.OFFICE_ID).eq(office.toUpperCase()));
}

RecordMapper<Record, Clob> mapper = joinRecord ->
new Clob(joinRecord.get(ao.OFFICE_ID),
joinRecord.get(ac.ID),
joinRecord.get(ac.DESCRIPTION),
joinRecord.get(ac.VALUE)
new Clob(joinRecord.get(vOffice.OFFICE_ID),
joinRecord.get(vClob.ID),
joinRecord.get(vClob.DESCRIPTION),
joinRecord.get(vClob.VALUE)
);

return dsl.select(ac.asterisk(), ao.OFFICE_ID).from(
ac.join(ao).on(ac.OFFICE_CODE.eq(ao.OFFICE_CODE))).where(cond).fetch(mapper);
}

public String getClobValue(String office, String id) {
AV_CLOB ac = AV_CLOB.AV_CLOB;
AV_OFFICE ao = AV_OFFICE.AV_OFFICE;

Condition cond = ac.ID.eq(id).and(ao.OFFICE_ID.eq(office));

Record1<String> clobRecord = dsl.select(ac.VALUE).from(
ac.join(ao).on(ac.OFFICE_CODE.eq(ao.OFFICE_CODE))).where(cond).fetchOne();

return clobRecord.value1();
return dsl.select(vClob.asterisk(), vOffice.OFFICE_ID)
.from(vClob.join(vOffice).on(vClob.OFFICE_CODE.eq(vOffice.OFFICE_CODE)))
.where(cond)
.orderBy(vOffice.OFFICE_ID, vClob.ID)
.fetch(mapper);
}

public void create(Clob clob, boolean failIfExists) {
Expand Down Expand Up @@ -224,21 +195,21 @@ public void delete(String officeId, String id) {

public void update(Clob clob, boolean ignoreNulls) {

String p_ignore_nulls = getBoolean(ignoreNulls);
String pIgnoreNulls = getBoolean(ignoreNulls);

// Note: when p_ignore_nulls == 'T' and the value or description is "" (not null)
// Note: when pIgnoreNulls == 'T' and the value or description is "" (not null)
// the field is not updated.
// Also note: when p_ignore_nulls == 'F' and the value is null
// Also note: when pIgnoreNulls == 'F' and the value is null
// it throws - ORA-20244: NULL_ARGUMENT: Argument P_TEXT is not allowed to be null
// Also note: when p_ignore_nulls == 'F' and the value is "" (empty string)
// Also note: when pIgnoreNulls == 'F' and the value is "" (empty string)
// it throws - ORA-20244: NULL_ARGUMENT: Argument P_TEXT is not allowed to be null
dsl.connection(c ->
CWMS_TEXT_PACKAGE.call_UPDATE_TEXT(
getDslContext(c,clob.getOfficeId()).configuration(),
clob.getValue(),
clob.getId(),
clob.getDescription(),
p_ignore_nulls,
pIgnoreNulls,
clob.getOfficeId()
)
);
Expand Down Expand Up @@ -269,11 +240,7 @@ public void getClob(String clobId, String officeId, ClobConsumer clobConsumer) {
try (ResultSet resultSet = preparedStatement.executeQuery()) {
if (resultSet.next()) {
java.sql.Clob clob = resultSet.getClob("VALUE");
if (clob != null) {
clobConsumer.accept(clob);
} else {
clobConsumer.accept(null);
}
clobConsumer.accept(clob);
} else {
throw new NotFoundException("Unable to find clob with id " + clobId + " in office " + officeId);
}
Expand Down
4 changes: 0 additions & 4 deletions cwms-data-api/src/main/java/cwms/cda/data/dao/Dao.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
import cwms.cda.data.dto.CwmsDTO;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import org.jooq.DSLContext;
Expand Down Expand Up @@ -107,9 +106,6 @@ protected void setOffice(Connection c, String office) throws SQLException {
CWMS_ENV_PACKAGE.call_SET_SESSION_OFFICE_ID(DSL.using(c).configuration(), office);
}


public abstract List<T> getAll(String office);

public abstract Optional<T> getByUniqueName(String uniqueName, String office);

/**
Expand Down
11 changes: 2 additions & 9 deletions cwms-data-api/src/main/java/cwms/cda/data/dao/JooqDao.java
Original file line number Diff line number Diff line change
Expand Up @@ -166,11 +166,6 @@ private static Connection setClientInfo(Context ctx, Connection connection) {
return connection;
}

@Override
public List<T> getAll(String officeId) {
throw new UnsupportedOperationException("Not supported yet.");
}

@Override
public Optional<T> getByUniqueName(String uniqueName, String officeId) {
throw new UnsupportedOperationException("Not supported yet.");
Expand Down Expand Up @@ -319,10 +314,8 @@ public static boolean isNotFound(RuntimeException input) {

public static boolean isInvalidOffice(RuntimeException input) {
return getSqlException(input)
.map(sqlException -> {
return hasCodeOrMessage(sqlException, Collections.singletonList(20010),
Collections.singletonList("INVALID_OFFICE_ID"));
})
.map(sqlException -> hasCodeOrMessage(sqlException, Collections.singletonList(20010),
Collections.singletonList("INVALID_OFFICE_ID")))
.orElse(false);
}

Expand Down
Loading

0 comments on commit c224cc5

Please sign in to comment.