Merged feature/workflows-support into integration

This commit is contained in:
2025-07-17 15:28:00 -05:00
3 changed files with 70 additions and 15 deletions

View File

@ -30,7 +30,6 @@ import java.util.Map;
import com.kingsrook.qqq.backend.core.context.QContext; import com.kingsrook.qqq.backend.core.context.QContext;
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter; import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter;
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryJoin; import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryJoin;
import com.kingsrook.qqq.backend.core.model.metadata.joins.QJoinMetaData;
import com.kingsrook.qqq.backend.core.utils.JsonUtils; import com.kingsrook.qqq.backend.core.utils.JsonUtils;
import com.kingsrook.qqq.middleware.javalin.specs.v1.responses.components.TableVariant; import com.kingsrook.qqq.middleware.javalin.specs.v1.responses.components.TableVariant;
import com.kingsrook.qqq.openapi.model.Content; import com.kingsrook.qqq.openapi.model.Content;
@ -101,7 +100,7 @@ public class QuerySpecUtils
***************************************************************************/ ***************************************************************************/
public static List<QueryJoin> getJoinsFromRequestBody(JSONObject requestBody) throws IOException public static List<QueryJoin> getJoinsFromRequestBody(JSONObject requestBody) throws IOException
{ {
if(requestBody.has("joins")) if(requestBody.has("joins") && !requestBody.isNull("joins"))
{ {
Object joinsFromJson = requestBody.get("joins"); Object joinsFromJson = requestBody.get("joins");
if(joinsFromJson instanceof JSONArray joinsJsonArray) if(joinsFromJson instanceof JSONArray joinsJsonArray)
@ -110,18 +109,32 @@ public class QuerySpecUtils
for(int i = 0; i < joinsJsonArray.length(); i++) for(int i = 0; i < joinsJsonArray.length(); i++)
{ {
JSONObject joinJsonObject = joinsJsonArray.getJSONObject(i); JSONObject joinJsonObject = joinsJsonArray.getJSONObject(i);
QJoinMetaData joinMetaData = null; QueryJoin queryJoin = new QueryJoin();
if(joinJsonObject.has("joinName")) joins.add(queryJoin);
queryJoin.setJoinTable(joinJsonObject.optString("joinTable"));
if(joinJsonObject.has("baseTableOrAlias") && !joinJsonObject.isNull("baseTableOrAlias"))
{ {
String joinName = joinJsonObject.getString("joinName"); queryJoin.setBaseTableOrAlias(joinJsonObject.optString("baseTableOrAlias"));
joinMetaData = QContext.getQInstance().getJoin(joinName);
joinJsonObject.remove("joinName");
} }
QueryJoin queryJoin = JsonUtils.toObject(joinJsonObject.toString(), QueryJoin.class); if(joinJsonObject.has("alias") && !joinJsonObject.isNull("alias"))
queryJoin.setJoinMetaData(joinMetaData); {
queryJoin.setAlias(joinJsonObject.optString("alias"));
}
joins.add(queryJoin); queryJoin.setSelect(joinJsonObject.optBoolean("select"));
if(joinJsonObject.has("type") && !joinJsonObject.isNull("type"))
{
queryJoin.setType(QueryJoin.Type.valueOf(joinJsonObject.getString("type")));
}
if(joinJsonObject.has("joinName") && !joinJsonObject.isNull("joinName"))
{
queryJoin.setJoinMetaData(QContext.getQInstance().getJoin(joinJsonObject.getString("joinName")));
}
} }
return (joins); return (joins);
} }

View File

@ -86,6 +86,7 @@ import com.kingsrook.qqq.backend.core.model.metadata.reporting.QReportView;
import com.kingsrook.qqq.backend.core.model.metadata.reporting.ReportType; import com.kingsrook.qqq.backend.core.model.metadata.reporting.ReportType;
import com.kingsrook.qqq.backend.core.model.metadata.tables.AssociatedScript; import com.kingsrook.qqq.backend.core.model.metadata.tables.AssociatedScript;
import com.kingsrook.qqq.backend.core.model.metadata.tables.Association; import com.kingsrook.qqq.backend.core.model.metadata.tables.Association;
import com.kingsrook.qqq.backend.core.model.metadata.tables.ExposedJoin;
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData; import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
import com.kingsrook.qqq.backend.core.model.metadata.variants.BackendVariantsConfig; import com.kingsrook.qqq.backend.core.model.metadata.variants.BackendVariantsConfig;
import com.kingsrook.qqq.backend.core.model.savedviews.SavedViewsMetaDataProvider; import com.kingsrook.qqq.backend.core.model.savedviews.SavedViewsMetaDataProvider;
@ -120,6 +121,9 @@ public class TestUtils
public static final String TABLE_NAME_MEMORY_VARIANT_OPTIONS = "memoryVariantOptions"; public static final String TABLE_NAME_MEMORY_VARIANT_OPTIONS = "memoryVariantOptions";
public static final String TABLE_NAME_MEMORY_VARIANT_DATA = "memoryVariantData"; public static final String TABLE_NAME_MEMORY_VARIANT_DATA = "memoryVariantData";
private static final String PERSON_JOIN_PET = "personJoinPet";
private static final String PERSON_JOIN_PARTNER_PERSON = "PersonJoinPartnerPerson";
public static final String PROCESS_NAME_GREET_PEOPLE_INTERACTIVE = "greetInteractive"; public static final String PROCESS_NAME_GREET_PEOPLE_INTERACTIVE = "greetInteractive";
public static final String PROCESS_NAME_SIMPLE_SLEEP = "simpleSleep"; public static final String PROCESS_NAME_SIMPLE_SLEEP = "simpleSleep";
public static final String PROCESS_NAME_SIMPLE_THROW = "simpleThrow"; public static final String PROCESS_NAME_SIMPLE_THROW = "simpleThrow";
@ -401,7 +405,9 @@ public class TestUtils
.withField(new QFieldMetaData("photoFileName", QFieldType.STRING).withBackendName("photo_file_name")) .withField(new QFieldMetaData("photoFileName", QFieldType.STRING).withBackendName("photo_file_name"))
.withField(new QFieldMetaData("licenseScanPdfUrl", QFieldType.STRING).withBackendName("license_scan_pdf_url")) .withField(new QFieldMetaData("licenseScanPdfUrl", QFieldType.STRING).withBackendName("license_scan_pdf_url"))
.withAssociation(new Association().withName("pets").withJoinName("personJoinPet").withAssociatedTableName(TABLE_NAME_PET)) .withExposedJoin(new ExposedJoin().withJoinTable(TABLE_NAME_PET).withLabel("Pets").withJoinPath(List.of(PERSON_JOIN_PET)))
.withAssociation(new Association().withName("pets").withJoinName(PERSON_JOIN_PET).withAssociatedTableName(TABLE_NAME_PET))
.withAssociatedScript(new AssociatedScript() .withAssociatedScript(new AssociatedScript()
.withFieldName("testScriptId") .withFieldName("testScriptId")
.withScriptTypeId(1) .withScriptTypeId(1)
@ -509,7 +515,7 @@ public class TestUtils
.withLeftTable(TABLE_NAME_PERSON) .withLeftTable(TABLE_NAME_PERSON)
.withRightTable(TABLE_NAME_PERSON) .withRightTable(TABLE_NAME_PERSON)
.withType(JoinType.MANY_TO_ONE) .withType(JoinType.MANY_TO_ONE)
.withName("PersonJoinPartnerPerson") .withName(PERSON_JOIN_PARTNER_PERSON)
.withJoinOn(new JoinOn("partnerPersonId", "id"))); .withJoinOn(new JoinOn("partnerPersonId", "id")));
} }
@ -524,7 +530,7 @@ public class TestUtils
.withLeftTable(TABLE_NAME_PERSON) .withLeftTable(TABLE_NAME_PERSON)
.withRightTable(TABLE_NAME_PET) .withRightTable(TABLE_NAME_PET)
.withType(JoinType.ONE_TO_MANY) .withType(JoinType.ONE_TO_MANY)
.withName("personJoinPet") .withName(PERSON_JOIN_PET)
.withJoinOn(new JoinOn("id", "ownerPersonId"))); .withJoinOn(new JoinOn("id", "ownerPersonId")));
} }

View File

@ -34,6 +34,7 @@ import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter;
import com.kingsrook.qqq.backend.core.model.data.QRecord; import com.kingsrook.qqq.backend.core.model.data.QRecord;
import com.kingsrook.qqq.backend.core.model.session.QSystemUserSession; import com.kingsrook.qqq.backend.core.model.session.QSystemUserSession;
import com.kingsrook.qqq.backend.core.utils.JsonUtils; import com.kingsrook.qqq.backend.core.utils.JsonUtils;
import com.kingsrook.qqq.backend.core.utils.collections.MapBuilder;
import com.kingsrook.qqq.backend.javalin.TestUtils; import com.kingsrook.qqq.backend.javalin.TestUtils;
import com.kingsrook.qqq.middleware.javalin.specs.AbstractEndpointSpec; import com.kingsrook.qqq.middleware.javalin.specs.AbstractEndpointSpec;
import com.kingsrook.qqq.middleware.javalin.specs.SpecTestBase; import com.kingsrook.qqq.middleware.javalin.specs.SpecTestBase;
@ -102,6 +103,42 @@ class TableQuerySpecV1Test extends SpecTestBase
/*******************************************************************************
**
*******************************************************************************/
@Test
void testJoin()
{
HttpResponse<String> response = Unirest.post(getBaseUrlAndPath() + "/table/person/query")
.contentType(ContentType.APPLICATION_JSON.getMimeType())
.body(JsonUtils.toJson(Map.of(
"filter", new QQueryFilter(new QFilterCriteria("lastName", QCriteriaOperator.EQUALS, "Kelkhoff")),
"joins", List.of(MapBuilder.of(
"joinTable", TestUtils.TABLE_NAME_PET,
"select", true,
"type", "LEFT",
"alias", null,
"joinName", null,
"baseTableOrAlias", null
))
)))
.asString();
assertEquals(200, response.getStatus());
JSONObject jsonObject = JsonUtils.toJSONObject(response.getBody());
JSONArray records = jsonObject.getJSONArray("records");
assertThat(records.length()).isGreaterThanOrEqualTo(3);
JSONObject record = records.getJSONObject(0);
assertThat(record.getString("recordLabel")).contains("Kelkhoff");
assertThat(record.getString("tableName")).isEqualTo("person");
assertThat(record.getJSONObject("values").getString("lastName")).isEqualTo("Kelkhoff");
assertThat(record.getJSONObject("displayValues").getString("lastName")).isEqualTo("Kelkhoff");
assertThat(record.getJSONObject("displayValues").getString("pet.name")).isIn(List.of("Chester", "Lucy"));
}
/******************************************************************************* /*******************************************************************************
** **
*******************************************************************************/ *******************************************************************************/
@ -226,7 +263,6 @@ class TableQuerySpecV1Test extends SpecTestBase
assertEquals(500, response.getStatus()); assertEquals(500, response.getStatus());
jsonObject = JsonUtils.toJSONObject(response.getBody()); jsonObject = JsonUtils.toJSONObject(response.getBody());
assertEquals("Could not find Backend Variant in table memoryVariantOptions with id '3'", jsonObject.getString("error")); assertEquals("Could not find Backend Variant in table memoryVariantOptions with id '3'", jsonObject.getString("error"));
} }
} }