mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-18 13:10:44 +00:00
Checkpoint: Added Update (edit) action
This commit is contained in:
@ -5,6 +5,8 @@
|
|||||||
package com.kingsrook.qqq.backend.javalin;
|
package com.kingsrook.qqq.backend.javalin;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -15,6 +17,8 @@ import com.kingsrook.qqq.backend.core.actions.InsertAction;
|
|||||||
import com.kingsrook.qqq.backend.core.actions.MetaDataAction;
|
import com.kingsrook.qqq.backend.core.actions.MetaDataAction;
|
||||||
import com.kingsrook.qqq.backend.core.actions.QueryAction;
|
import com.kingsrook.qqq.backend.core.actions.QueryAction;
|
||||||
import com.kingsrook.qqq.backend.core.actions.TableMetaDataAction;
|
import com.kingsrook.qqq.backend.core.actions.TableMetaDataAction;
|
||||||
|
import com.kingsrook.qqq.backend.core.actions.UpdateAction;
|
||||||
|
import com.kingsrook.qqq.backend.core.adapters.QInstanceAdapter;
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QModuleDispatchException;
|
import com.kingsrook.qqq.backend.core.exceptions.QModuleDispatchException;
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QUserFacingException;
|
import com.kingsrook.qqq.backend.core.exceptions.QUserFacingException;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.AbstractQRequest;
|
import com.kingsrook.qqq.backend.core.model.actions.AbstractQRequest;
|
||||||
@ -29,8 +33,11 @@ import com.kingsrook.qqq.backend.core.model.actions.metadata.table.TableMetaData
|
|||||||
import com.kingsrook.qqq.backend.core.model.actions.query.QQueryFilter;
|
import com.kingsrook.qqq.backend.core.model.actions.query.QQueryFilter;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.query.QueryRequest;
|
import com.kingsrook.qqq.backend.core.model.actions.query.QueryRequest;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.query.QueryResult;
|
import com.kingsrook.qqq.backend.core.model.actions.query.QueryResult;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.actions.update.UpdateRequest;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.actions.update.UpdateResult;
|
||||||
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.metadata.QInstance;
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.QTableMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.model.session.QSession;
|
import com.kingsrook.qqq.backend.core.model.session.QSession;
|
||||||
import com.kingsrook.qqq.backend.core.modules.QAuthenticationModuleDispatcher;
|
import com.kingsrook.qqq.backend.core.modules.QAuthenticationModuleDispatcher;
|
||||||
import com.kingsrook.qqq.backend.core.modules.interfaces.QAuthenticationModuleInterface;
|
import com.kingsrook.qqq.backend.core.modules.interfaces.QAuthenticationModuleInterface;
|
||||||
@ -40,6 +47,7 @@ import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
|||||||
import io.javalin.Javalin;
|
import io.javalin.Javalin;
|
||||||
import io.javalin.apibuilder.EndpointGroup;
|
import io.javalin.apibuilder.EndpointGroup;
|
||||||
import io.javalin.http.Context;
|
import io.javalin.http.Context;
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.eclipse.jetty.http.HttpStatus;
|
import org.eclipse.jetty.http.HttpStatus;
|
||||||
@ -48,6 +56,7 @@ import static io.javalin.apibuilder.ApiBuilder.get;
|
|||||||
import static io.javalin.apibuilder.ApiBuilder.patch;
|
import static io.javalin.apibuilder.ApiBuilder.patch;
|
||||||
import static io.javalin.apibuilder.ApiBuilder.path;
|
import static io.javalin.apibuilder.ApiBuilder.path;
|
||||||
import static io.javalin.apibuilder.ApiBuilder.post;
|
import static io.javalin.apibuilder.ApiBuilder.post;
|
||||||
|
import static io.javalin.apibuilder.ApiBuilder.put;
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@ -91,12 +100,13 @@ public class QJavalinImplementation
|
|||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Setter for qInstance
|
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public static void setQInstance(QInstance qInstance)
|
public QJavalinImplementation(String qInstanceFilePath) throws IOException
|
||||||
{
|
{
|
||||||
QJavalinImplementation.qInstance = qInstance;
|
LOG.info("Loading qInstance from file (assuming json): " + qInstanceFilePath);
|
||||||
|
String qInstanceJson = FileUtils.readFileToString(new File(qInstanceFilePath));
|
||||||
|
QJavalinImplementation.qInstance = new QInstanceAdapter().jsonToQInstanceIncludingBackends(qInstanceJson);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -134,11 +144,13 @@ public class QJavalinImplementation
|
|||||||
path("/:table", () ->
|
path("/:table", () ->
|
||||||
{
|
{
|
||||||
get("/", QJavalinImplementation::dataQuery);
|
get("/", QJavalinImplementation::dataQuery);
|
||||||
post("/", QJavalinImplementation::dataInsert);
|
post("/", QJavalinImplementation::dataInsert); // todo - internal to that method, if input is a list, do a bulk - else, single.
|
||||||
path("/:id", () ->
|
// todo - add put and/or patch at this level (without a primaryKey) to do a bulk update based on primaryKeys in the records.
|
||||||
|
path("/:primaryKey", () ->
|
||||||
{
|
{
|
||||||
get("", QJavalinImplementation::dataGet);
|
get("", QJavalinImplementation::dataGet);
|
||||||
patch("", QJavalinImplementation::dataUpdate);
|
patch("", QJavalinImplementation::dataUpdate);
|
||||||
|
put("", QJavalinImplementation::dataUpdate); // todo - want different semantics??
|
||||||
delete("", QJavalinImplementation::dataDelete);
|
delete("", QJavalinImplementation::dataDelete);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -176,7 +188,7 @@ public class QJavalinImplementation
|
|||||||
{
|
{
|
||||||
String table = context.pathParam("table");
|
String table = context.pathParam("table");
|
||||||
List<Serializable> primaryKeys = new ArrayList<>();
|
List<Serializable> primaryKeys = new ArrayList<>();
|
||||||
primaryKeys.add(context.pathParam("id"));
|
primaryKeys.add(context.pathParam("primaryKey"));
|
||||||
|
|
||||||
DeleteRequest deleteRequest = new DeleteRequest(qInstance);
|
DeleteRequest deleteRequest = new DeleteRequest(qInstance);
|
||||||
setupSession(context, deleteRequest);
|
setupSession(context, deleteRequest);
|
||||||
@ -201,7 +213,41 @@ public class QJavalinImplementation
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
private static void dataUpdate(Context context)
|
private static void dataUpdate(Context context)
|
||||||
{
|
{
|
||||||
context.result("{\"todo\":\"not-done\",\"updateResult\":{}}");
|
try
|
||||||
|
{
|
||||||
|
String table = context.pathParam("table");
|
||||||
|
List<QRecord> recordList = new ArrayList<>();
|
||||||
|
QRecord record = new QRecord();
|
||||||
|
record.setTableName(table);
|
||||||
|
recordList.add(record);
|
||||||
|
|
||||||
|
Map<?, ?> map = context.bodyAsClass(Map.class);
|
||||||
|
for(Map.Entry<?, ?> entry : map.entrySet())
|
||||||
|
{
|
||||||
|
if(StringUtils.hasContent(String.valueOf(entry.getValue())))
|
||||||
|
{
|
||||||
|
record.setValue(String.valueOf(entry.getKey()), (Serializable) entry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QTableMetaData tableMetaData = qInstance.getTable(table);
|
||||||
|
|
||||||
|
record.setValue(tableMetaData.getPrimaryKeyField(), context.pathParam("primaryKey"));
|
||||||
|
|
||||||
|
UpdateRequest updateRequest = new UpdateRequest(qInstance);
|
||||||
|
setupSession(context, updateRequest);
|
||||||
|
updateRequest.setTableName(table);
|
||||||
|
updateRequest.setRecords(recordList);
|
||||||
|
|
||||||
|
UpdateAction updateAction = new UpdateAction();
|
||||||
|
UpdateResult updateResult = updateAction.execute(updateRequest);
|
||||||
|
|
||||||
|
context.result(JsonUtils.toJson(updateResult));
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
handleException(context, e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ import org.junit.jupiter.api.BeforeAll;
|
|||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
@ -147,9 +147,9 @@ class QJavalinImplementationTest
|
|||||||
JSONObject record0 = records.getJSONObject(0);
|
JSONObject record0 = records.getJSONObject(0);
|
||||||
assertTrue(record0.has("values"));
|
assertTrue(record0.has("values"));
|
||||||
assertEquals("person", record0.getString("tableName"));
|
assertEquals("person", record0.getString("tableName"));
|
||||||
assertTrue(record0.has("primaryKey"));
|
|
||||||
JSONObject values0 = record0.getJSONObject("values");
|
JSONObject values0 = record0.getJSONObject("values");
|
||||||
assertTrue(values0.has("firstName"));
|
assertTrue(values0.has("firstName"));
|
||||||
|
assertTrue(values0.has("id"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -200,10 +200,42 @@ class QJavalinImplementationTest
|
|||||||
JSONObject record0 = records.getJSONObject(0);
|
JSONObject record0 = records.getJSONObject(0);
|
||||||
assertTrue(record0.has("values"));
|
assertTrue(record0.has("values"));
|
||||||
assertEquals("person", record0.getString("tableName"));
|
assertEquals("person", record0.getString("tableName"));
|
||||||
assertTrue(record0.has("primaryKey"));
|
|
||||||
JSONObject values0 = record0.getJSONObject("values");
|
JSONObject values0 = record0.getJSONObject("values");
|
||||||
assertTrue(values0.has("firstName"));
|
assertTrue(values0.has("firstName"));
|
||||||
assertEquals("Bobby", values0.getString("firstName"));
|
assertEquals("Bobby", values0.getString("firstName"));
|
||||||
|
assertTrue(values0.has("id"));
|
||||||
|
assertEquals(6, values0.getInt("id"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** test an update
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
public void test_dataUpdate()
|
||||||
|
{
|
||||||
|
Map<String, Serializable> body = new HashMap<>();
|
||||||
|
body.put("firstName", "Free");
|
||||||
|
//? body.put("id", 4);
|
||||||
|
|
||||||
|
HttpResponse<String> response = Unirest.patch(BASE_URL + "/data/person/4")
|
||||||
|
.header("Content-Type", "application/json")
|
||||||
|
.body(body)
|
||||||
|
.asString();
|
||||||
|
|
||||||
|
assertEquals(200, response.getStatus());
|
||||||
|
JSONObject jsonObject = JsonUtils.toJSONObject(response.getBody());
|
||||||
|
assertTrue(jsonObject.has("records"));
|
||||||
|
JSONArray records = jsonObject.getJSONArray("records");
|
||||||
|
assertEquals(1, records.length());
|
||||||
|
JSONObject record0 = records.getJSONObject(0);
|
||||||
|
assertTrue(record0.has("values"));
|
||||||
|
assertEquals("person", record0.getString("tableName"));
|
||||||
|
JSONObject values0 = record0.getJSONObject("values");
|
||||||
|
assertEquals(4, values0.getInt("id"));
|
||||||
|
assertEquals("Free", values0.getString("firstName"));
|
||||||
|
// mmm, whole record isn't loaded. should it be? assertEquals("Samples", values0.getString("lastName"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -224,13 +256,13 @@ class QJavalinImplementationTest
|
|||||||
JSONObject jsonObject = JsonUtils.toJSONObject(response.getBody());
|
JSONObject jsonObject = JsonUtils.toJSONObject(response.getBody());
|
||||||
assertNotNull(jsonObject);
|
assertNotNull(jsonObject);
|
||||||
assertEquals(1, jsonObject.getJSONArray("records").length());
|
assertEquals(1, jsonObject.getJSONArray("records").length());
|
||||||
assertEquals(3, jsonObject.getJSONArray("records").getJSONObject(0).getInt("primaryKey"));
|
assertEquals(3, jsonObject.getJSONArray("records").getJSONObject(0).getJSONObject("values").getInt("id"));
|
||||||
TestUtils.runTestSql("SELECT id FROM person", (rs -> {
|
TestUtils.runTestSql("SELECT id FROM person", (rs -> {
|
||||||
int rowsFound = 0;
|
int rowsFound = 0;
|
||||||
while(rs.next())
|
while(rs.next())
|
||||||
{
|
{
|
||||||
rowsFound++;
|
rowsFound++;
|
||||||
assertFalse(rs.getInt(1) == 3);
|
assertNotEquals(3, rs.getInt(1));
|
||||||
}
|
}
|
||||||
assertEquals(4, rowsFound);
|
assertEquals(4, rowsFound);
|
||||||
}));
|
}));
|
||||||
|
Reference in New Issue
Block a user