mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-18 05:01:07 +00:00
Add GET action, and usage in API
This commit is contained in:
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* QQQ - Low-code Application Framework for Engineers.
|
||||||
|
* Copyright (C) 2021-2022. Kingsrook, LLC
|
||||||
|
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||||
|
* contact@kingsrook.com
|
||||||
|
* https://github.com/Kingsrook/
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.kingsrook.qqq.backend.core.actions.interfaces;
|
||||||
|
|
||||||
|
|
||||||
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.actions.tables.get.GetInput;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.actions.tables.get.GetOutput;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Interface for the Get action.
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public interface GetInterface
|
||||||
|
{
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
GetOutput execute(GetInput getInput) throws QException;
|
||||||
|
}
|
@ -0,0 +1,161 @@
|
|||||||
|
/*
|
||||||
|
* QQQ - Low-code Application Framework for Engineers.
|
||||||
|
* Copyright (C) 2021-2022. Kingsrook, LLC
|
||||||
|
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||||
|
* contact@kingsrook.com
|
||||||
|
* https://github.com/Kingsrook/
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.kingsrook.qqq.backend.core.actions.tables;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import com.kingsrook.qqq.backend.core.actions.ActionHelper;
|
||||||
|
import com.kingsrook.qqq.backend.core.actions.customizers.QCodeLoader;
|
||||||
|
import com.kingsrook.qqq.backend.core.actions.customizers.TableCustomizers;
|
||||||
|
import com.kingsrook.qqq.backend.core.actions.interfaces.GetInterface;
|
||||||
|
import com.kingsrook.qqq.backend.core.actions.values.QPossibleValueTranslator;
|
||||||
|
import com.kingsrook.qqq.backend.core.actions.values.QValueFormatter;
|
||||||
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.actions.tables.get.GetInput;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.actions.tables.get.GetOutput;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterCriteria;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryInput;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryOutput;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
||||||
|
import com.kingsrook.qqq.backend.core.modules.backend.QBackendModuleDispatcher;
|
||||||
|
import com.kingsrook.qqq.backend.core.modules.backend.QBackendModuleInterface;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Action to run a get against a table.
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public class GetAction
|
||||||
|
{
|
||||||
|
private Optional<Function<QRecord, QRecord>> postGetRecordCustomizer;
|
||||||
|
|
||||||
|
private GetInput getInput;
|
||||||
|
private QValueFormatter qValueFormatter;
|
||||||
|
private QPossibleValueTranslator qPossibleValueTranslator;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public GetOutput execute(GetInput getInput) throws QException
|
||||||
|
{
|
||||||
|
ActionHelper.validateSession(getInput);
|
||||||
|
|
||||||
|
postGetRecordCustomizer = QCodeLoader.getTableCustomizerFunction(getInput.getTable(), TableCustomizers.POST_QUERY_RECORD.getRole());
|
||||||
|
this.getInput = getInput;
|
||||||
|
|
||||||
|
QBackendModuleDispatcher qBackendModuleDispatcher = new QBackendModuleDispatcher();
|
||||||
|
QBackendModuleInterface qModule = qBackendModuleDispatcher.getQBackendModule(getInput.getBackend());
|
||||||
|
// todo pre-customization - just get to modify the request?
|
||||||
|
|
||||||
|
GetInterface getInterface = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
getInterface = qModule.getGetInterface();
|
||||||
|
}
|
||||||
|
catch(IllegalStateException ise)
|
||||||
|
{
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// if a module doesn't implement Get directly - try to do a Get by a Query by the primary key //
|
||||||
|
// see below. //
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
}
|
||||||
|
|
||||||
|
GetOutput getOutput;
|
||||||
|
if(getInterface != null)
|
||||||
|
{
|
||||||
|
getOutput = getInterface.execute(getInput);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
getOutput = performGetViaQuery(getInput);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(getOutput.getRecord() != null)
|
||||||
|
{
|
||||||
|
getOutput.setRecord(postRecordActions(getOutput.getRecord()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return getOutput;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
private GetOutput performGetViaQuery(GetInput getInput) throws QException
|
||||||
|
{
|
||||||
|
QueryInput queryInput = new QueryInput(getInput.getInstance());
|
||||||
|
queryInput.setSession(getInput.getSession());
|
||||||
|
queryInput.setTableName(getInput.getTableName());
|
||||||
|
queryInput.setFilter(new QQueryFilter().withCriteria(new QFilterCriteria(getInput.getTable().getPrimaryKeyField(), QCriteriaOperator.EQUALS, List.of(getInput.getPrimaryKey()))));
|
||||||
|
QueryOutput queryOutput = new QueryAction().execute(queryInput);
|
||||||
|
|
||||||
|
GetOutput getOutput = new GetOutput();
|
||||||
|
if(!queryOutput.getRecords().isEmpty())
|
||||||
|
{
|
||||||
|
getOutput.setRecord(queryOutput.getRecords().get(0));
|
||||||
|
}
|
||||||
|
return (getOutput);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Run the necessary actions on a record. This may include setting display values,
|
||||||
|
** translating possible values, and running post-record customizations.
|
||||||
|
*******************************************************************************/
|
||||||
|
public QRecord postRecordActions(QRecord record)
|
||||||
|
{
|
||||||
|
QRecord returnRecord = record;
|
||||||
|
if(this.postGetRecordCustomizer.isPresent())
|
||||||
|
{
|
||||||
|
returnRecord = postGetRecordCustomizer.get().apply(record);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(getInput.getShouldTranslatePossibleValues())
|
||||||
|
{
|
||||||
|
if(qPossibleValueTranslator == null)
|
||||||
|
{
|
||||||
|
qPossibleValueTranslator = new QPossibleValueTranslator(getInput.getInstance(), getInput.getSession());
|
||||||
|
}
|
||||||
|
qPossibleValueTranslator.translatePossibleValuesInRecords(getInput.getTable(), List.of(returnRecord));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(getInput.getShouldGenerateDisplayValues())
|
||||||
|
{
|
||||||
|
if(qValueFormatter == null)
|
||||||
|
{
|
||||||
|
qValueFormatter = new QValueFormatter();
|
||||||
|
}
|
||||||
|
qValueFormatter.setDisplayValuesInRecords(getInput.getTable(), List.of(returnRecord));
|
||||||
|
}
|
||||||
|
|
||||||
|
return (returnRecord);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,186 @@
|
|||||||
|
/*
|
||||||
|
* QQQ - Low-code Application Framework for Engineers.
|
||||||
|
* Copyright (C) 2021-2022. Kingsrook, LLC
|
||||||
|
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||||
|
* contact@kingsrook.com
|
||||||
|
* https://github.com/Kingsrook/
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.kingsrook.qqq.backend.core.model.actions.tables.get;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import com.kingsrook.qqq.backend.core.actions.QBackendTransaction;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.actions.AbstractTableActionInput;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.session.QSession;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Input data for the Get action
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public class GetInput extends AbstractTableActionInput
|
||||||
|
{
|
||||||
|
private QBackendTransaction transaction;
|
||||||
|
private Serializable primaryKey;
|
||||||
|
|
||||||
|
private boolean shouldTranslatePossibleValues = false;
|
||||||
|
private boolean shouldGenerateDisplayValues = false;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public GetInput()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public GetInput(QInstance instance)
|
||||||
|
{
|
||||||
|
super(instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public GetInput(QInstance instance, QSession session)
|
||||||
|
{
|
||||||
|
super(instance);
|
||||||
|
setSession(session);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for primaryKey
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public Serializable getPrimaryKey()
|
||||||
|
{
|
||||||
|
return primaryKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for primaryKey
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setPrimaryKey(Serializable primaryKey)
|
||||||
|
{
|
||||||
|
this.primaryKey = primaryKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for primaryKey
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public GetInput withPrimaryKey(Serializable primaryKey)
|
||||||
|
{
|
||||||
|
this.primaryKey = primaryKey;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for shouldTranslatePossibleValues
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public boolean getShouldTranslatePossibleValues()
|
||||||
|
{
|
||||||
|
return shouldTranslatePossibleValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for shouldTranslatePossibleValues
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setShouldTranslatePossibleValues(boolean shouldTranslatePossibleValues)
|
||||||
|
{
|
||||||
|
this.shouldTranslatePossibleValues = shouldTranslatePossibleValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for shouldGenerateDisplayValues
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public boolean getShouldGenerateDisplayValues()
|
||||||
|
{
|
||||||
|
return shouldGenerateDisplayValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for shouldGenerateDisplayValues
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setShouldGenerateDisplayValues(boolean shouldGenerateDisplayValues)
|
||||||
|
{
|
||||||
|
this.shouldGenerateDisplayValues = shouldGenerateDisplayValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for transaction
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public QBackendTransaction getTransaction()
|
||||||
|
{
|
||||||
|
return transaction;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for transaction
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setTransaction(QBackendTransaction transaction)
|
||||||
|
{
|
||||||
|
this.transaction = transaction;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for transaction
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public GetInput withTransaction(QBackendTransaction transaction)
|
||||||
|
{
|
||||||
|
this.transaction = transaction;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* QQQ - Low-code Application Framework for Engineers.
|
||||||
|
* Copyright (C) 2021-2022. Kingsrook, LLC
|
||||||
|
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||||
|
* contact@kingsrook.com
|
||||||
|
* https://github.com/Kingsrook/
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.kingsrook.qqq.backend.core.model.actions.tables.get;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.actions.AbstractActionOutput;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Output for a Get action
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public class GetOutput extends AbstractActionOutput implements Serializable
|
||||||
|
{
|
||||||
|
private QRecord record;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for record
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public QRecord getRecord()
|
||||||
|
{
|
||||||
|
return record;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for record
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setRecord(QRecord record)
|
||||||
|
{
|
||||||
|
this.record = record;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for record
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public GetOutput withRecord(QRecord record)
|
||||||
|
{
|
||||||
|
this.record = record;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -24,6 +24,7 @@ package com.kingsrook.qqq.backend.core.modules.backend;
|
|||||||
|
|
||||||
import com.kingsrook.qqq.backend.core.actions.interfaces.CountInterface;
|
import com.kingsrook.qqq.backend.core.actions.interfaces.CountInterface;
|
||||||
import com.kingsrook.qqq.backend.core.actions.interfaces.DeleteInterface;
|
import com.kingsrook.qqq.backend.core.actions.interfaces.DeleteInterface;
|
||||||
|
import com.kingsrook.qqq.backend.core.actions.interfaces.GetInterface;
|
||||||
import com.kingsrook.qqq.backend.core.actions.interfaces.InsertInterface;
|
import com.kingsrook.qqq.backend.core.actions.interfaces.InsertInterface;
|
||||||
import com.kingsrook.qqq.backend.core.actions.interfaces.QueryInterface;
|
import com.kingsrook.qqq.backend.core.actions.interfaces.QueryInterface;
|
||||||
import com.kingsrook.qqq.backend.core.actions.interfaces.UpdateInterface;
|
import com.kingsrook.qqq.backend.core.actions.interfaces.UpdateInterface;
|
||||||
@ -76,6 +77,15 @@ public interface QBackendModuleInterface
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
default GetInterface getGetInterface()
|
||||||
|
{
|
||||||
|
throwNotImplemented("Get");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
@ -23,9 +23,9 @@ package com.kingsrook.qqq.backend.core.utils;
|
|||||||
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.time.LocalDateTime;
|
import java.time.Instant;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.util.ArrayList;
|
||||||
import java.time.format.DateTimeParseException;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
@ -233,31 +233,54 @@ public class JsonUtils
|
|||||||
public static QRecord parseQRecord(JSONObject jsonObject, Map<String, QFieldMetaData> fields)
|
public static QRecord parseQRecord(JSONObject jsonObject, Map<String, QFieldMetaData> fields)
|
||||||
{
|
{
|
||||||
QRecord record = new QRecord();
|
QRecord record = new QRecord();
|
||||||
|
|
||||||
|
FIELDS_LOOP:
|
||||||
for(String fieldName : fields.keySet())
|
for(String fieldName : fields.keySet())
|
||||||
{
|
{
|
||||||
QFieldMetaData metaData = fields.get(fieldName);
|
QFieldMetaData metaData = fields.get(fieldName);
|
||||||
String backendName = metaData.getBackendName() != null ? metaData.getBackendName() : fieldName;
|
String backendName = metaData.getBackendName() != null ? metaData.getBackendName() : fieldName;
|
||||||
switch(metaData.getType())
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// if the field backend name has dots in it, interpret that to mean traversal down sub-objects //
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
JSONObject jsonObjectToUse = jsonObject;
|
||||||
|
if(backendName.contains("."))
|
||||||
{
|
{
|
||||||
case INTEGER -> record.setValue(fieldName, jsonObject.optInt(backendName));
|
ArrayList<String> levels = new ArrayList<>(List.of(backendName.split("\\.")));
|
||||||
case DECIMAL -> record.setValue(fieldName, jsonObject.optBigDecimal(backendName, null));
|
backendName = levels.remove(levels.size() - 1);
|
||||||
case BOOLEAN -> record.setValue(fieldName, jsonObject.optBoolean(backendName));
|
|
||||||
case DATE_TIME ->
|
for(String level : levels)
|
||||||
{
|
{
|
||||||
String dateTimeString = jsonObject.optString(backendName);
|
try
|
||||||
if(StringUtils.hasContent(dateTimeString))
|
|
||||||
{
|
{
|
||||||
try
|
jsonObjectToUse = jsonObjectToUse.optJSONObject(level);
|
||||||
|
if(jsonObjectToUse == null)
|
||||||
{
|
{
|
||||||
record.setValue(fieldName, LocalDateTime.parse(dateTimeString, DateTimeFormatter.ISO_ZONED_DATE_TIME));
|
continue FIELDS_LOOP;
|
||||||
}
|
|
||||||
catch(DateTimeParseException dtpe1)
|
|
||||||
{
|
|
||||||
record.setValue(fieldName, LocalDateTime.parse(dateTimeString, DateTimeFormatter.ISO_DATE_TIME));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
continue FIELDS_LOOP;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
default -> record.setValue(fieldName, jsonObject.optString(backendName));
|
}
|
||||||
|
|
||||||
|
switch(metaData.getType())
|
||||||
|
{
|
||||||
|
case INTEGER -> record.setValue(fieldName, jsonObjectToUse.optInt(backendName));
|
||||||
|
case DECIMAL -> record.setValue(fieldName, jsonObjectToUse.optBigDecimal(backendName, null));
|
||||||
|
case BOOLEAN -> record.setValue(fieldName, jsonObjectToUse.optBoolean(backendName));
|
||||||
|
case DATE_TIME ->
|
||||||
|
{
|
||||||
|
String dateTimeString = jsonObjectToUse.optString(backendName);
|
||||||
|
if(StringUtils.hasContent(dateTimeString))
|
||||||
|
{
|
||||||
|
Instant instant = ValueUtils.getValueAsInstant(dateTimeString);
|
||||||
|
record.setValue(fieldName, instant);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default -> record.setValue(fieldName, jsonObjectToUse.optString(backendName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@ import java.time.LocalDate;
|
|||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.LocalTime;
|
import java.time.LocalTime;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
|
import java.time.ZoneOffset;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.time.format.DateTimeParseException;
|
import java.time.format.DateTimeParseException;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
@ -498,6 +499,22 @@ public class ValueUtils
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return LocalDateTime.parse(s, DateTimeFormatter.ISO_ZONED_DATE_TIME).toInstant(ZoneOffset.UTC);
|
||||||
|
}
|
||||||
|
catch(DateTimeParseException e2)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return LocalDateTime.parse(s, DateTimeFormatter.ISO_DATE_TIME).toInstant(ZoneOffset.UTC);
|
||||||
|
}
|
||||||
|
catch(Exception e3)
|
||||||
|
{
|
||||||
|
// just throw the original
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
throw (e);
|
throw (e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* QQQ - Low-code Application Framework for Engineers.
|
||||||
|
* Copyright (C) 2021-2022. Kingsrook, LLC
|
||||||
|
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||||
|
* contact@kingsrook.com
|
||||||
|
* https://github.com/Kingsrook/
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.kingsrook.qqq.backend.core.actions.tables;
|
||||||
|
|
||||||
|
|
||||||
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.actions.tables.get.GetInput;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.actions.tables.get.GetOutput;
|
||||||
|
import com.kingsrook.qqq.backend.core.utils.TestUtils;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Unit test for GetAction
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
class GetActionTest
|
||||||
|
{
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** At the core level, there isn't much that can be asserted, as it uses the
|
||||||
|
** mock implementation - just confirming that all of the "wiring" works.
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
public void test() throws QException
|
||||||
|
{
|
||||||
|
GetInput request = new GetInput(TestUtils.defineInstance());
|
||||||
|
request.setSession(TestUtils.getMockSession());
|
||||||
|
request.setTableName("person");
|
||||||
|
request.setPrimaryKey(1);
|
||||||
|
request.setShouldGenerateDisplayValues(true);
|
||||||
|
request.setShouldTranslatePossibleValues(true);
|
||||||
|
GetOutput result = new GetAction().execute(request);
|
||||||
|
assertNotNull(result);
|
||||||
|
assertNotNull(result.getRecord());
|
||||||
|
}
|
||||||
|
}
|
@ -24,6 +24,7 @@ package com.kingsrook.qqq.backend.module.api;
|
|||||||
|
|
||||||
import com.kingsrook.qqq.backend.core.actions.interfaces.CountInterface;
|
import com.kingsrook.qqq.backend.core.actions.interfaces.CountInterface;
|
||||||
import com.kingsrook.qqq.backend.core.actions.interfaces.DeleteInterface;
|
import com.kingsrook.qqq.backend.core.actions.interfaces.DeleteInterface;
|
||||||
|
import com.kingsrook.qqq.backend.core.actions.interfaces.GetInterface;
|
||||||
import com.kingsrook.qqq.backend.core.actions.interfaces.InsertInterface;
|
import com.kingsrook.qqq.backend.core.actions.interfaces.InsertInterface;
|
||||||
import com.kingsrook.qqq.backend.core.actions.interfaces.QueryInterface;
|
import com.kingsrook.qqq.backend.core.actions.interfaces.QueryInterface;
|
||||||
import com.kingsrook.qqq.backend.core.actions.interfaces.UpdateInterface;
|
import com.kingsrook.qqq.backend.core.actions.interfaces.UpdateInterface;
|
||||||
@ -31,6 +32,7 @@ import com.kingsrook.qqq.backend.core.model.metadata.QBackendMetaData;
|
|||||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableBackendDetails;
|
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableBackendDetails;
|
||||||
import com.kingsrook.qqq.backend.core.modules.backend.QBackendModuleInterface;
|
import com.kingsrook.qqq.backend.core.modules.backend.QBackendModuleInterface;
|
||||||
import com.kingsrook.qqq.backend.module.api.actions.APICountAction;
|
import com.kingsrook.qqq.backend.module.api.actions.APICountAction;
|
||||||
|
import com.kingsrook.qqq.backend.module.api.actions.APIGetAction;
|
||||||
import com.kingsrook.qqq.backend.module.api.actions.APIInsertAction;
|
import com.kingsrook.qqq.backend.module.api.actions.APIInsertAction;
|
||||||
import com.kingsrook.qqq.backend.module.api.actions.APIQueryAction;
|
import com.kingsrook.qqq.backend.module.api.actions.APIQueryAction;
|
||||||
|
|
||||||
@ -94,6 +96,17 @@ public class APIBackendModule implements QBackendModuleInterface
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Override
|
||||||
|
public GetInterface getGetInterface()
|
||||||
|
{
|
||||||
|
return (new APIGetAction());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
@ -58,7 +58,7 @@ public class APICountAction extends AbstractAPIAction implements CountInterface
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
QQueryFilter filter = countInput.getFilter();
|
QQueryFilter filter = countInput.getFilter();
|
||||||
String paramString = apiActionUtil.buildQueryString(filter, null, null, table.getFields());
|
String paramString = apiActionUtil.buildQueryStringForGet(filter, null, null, table.getFields());
|
||||||
|
|
||||||
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
|
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
|
||||||
HttpClient client = httpClientBuilder.build();
|
HttpClient client = httpClientBuilder.build();
|
||||||
|
@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* QQQ - Low-code Application Framework for Engineers.
|
||||||
|
* Copyright (C) 2021-2022. Kingsrook, LLC
|
||||||
|
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||||
|
* contact@kingsrook.com
|
||||||
|
* https://github.com/Kingsrook/
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.kingsrook.qqq.backend.module.api.actions;
|
||||||
|
|
||||||
|
|
||||||
|
import com.kingsrook.qqq.backend.core.actions.interfaces.GetInterface;
|
||||||
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.actions.tables.get.GetInput;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.actions.tables.get.GetOutput;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
|
||||||
|
import org.apache.http.HttpResponse;
|
||||||
|
import org.apache.http.client.HttpClient;
|
||||||
|
import org.apache.http.client.methods.HttpGet;
|
||||||
|
import org.apache.http.impl.client.HttpClientBuilder;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public class APIGetAction extends AbstractAPIAction implements GetInterface
|
||||||
|
{
|
||||||
|
private static final Logger LOG = LogManager.getLogger(APIGetAction.class);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public GetOutput execute(GetInput getInput) throws QException
|
||||||
|
{
|
||||||
|
QTableMetaData table = getInput.getTable();
|
||||||
|
preAction(getInput);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String urlSuffix = apiActionUtil.buildUrlSuffixForSingleRecordGet(getInput.getPrimaryKey());
|
||||||
|
|
||||||
|
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
|
||||||
|
HttpClient client = httpClientBuilder.build();
|
||||||
|
|
||||||
|
String url = apiActionUtil.buildTableUrl(table);
|
||||||
|
HttpGet request = new HttpGet(url + urlSuffix);
|
||||||
|
|
||||||
|
apiActionUtil.setupAuthorizationInRequest(request);
|
||||||
|
apiActionUtil.setupContentTypeInRequest(request);
|
||||||
|
apiActionUtil.setupAdditionalHeaders(request);
|
||||||
|
|
||||||
|
HttpResponse response = client.execute(request);
|
||||||
|
QRecord record = apiActionUtil.processSingleRecordGetResponse(table, response);
|
||||||
|
|
||||||
|
GetOutput rs = new GetOutput();
|
||||||
|
rs.setRecord(record);
|
||||||
|
return rs;
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
LOG.warn("Error in API get", e);
|
||||||
|
throw new QException("Error executing get: " + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -58,7 +58,7 @@ public class APIQueryAction extends AbstractAPIAction implements QueryInterface
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
QQueryFilter filter = queryInput.getFilter();
|
QQueryFilter filter = queryInput.getFilter();
|
||||||
String paramString = apiActionUtil.buildQueryString(filter, queryInput.getLimit(), queryInput.getSkip(), table.getFields());
|
String paramString = apiActionUtil.buildQueryStringForGet(filter, queryInput.getLimit(), queryInput.getSkip(), table.getFields());
|
||||||
|
|
||||||
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
|
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
|
||||||
HttpClient client = httpClientBuilder.build();
|
HttpClient client = httpClientBuilder.build();
|
||||||
|
@ -32,14 +32,16 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.AbstractTableActionInput;
|
import com.kingsrook.qqq.backend.core.model.actions.AbstractTableActionInput;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterCriteria;
|
||||||
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.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.fields.QFieldMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
|
||||||
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.utils.CollectionUtils;
|
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
||||||
import com.kingsrook.qqq.backend.core.utils.JsonUtils;
|
import com.kingsrook.qqq.backend.core.utils.JsonUtils;
|
||||||
import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
||||||
|
import com.kingsrook.qqq.backend.core.utils.ValueUtils;
|
||||||
import com.kingsrook.qqq.backend.module.api.model.metadata.APIBackendMetaData;
|
import com.kingsrook.qqq.backend.module.api.model.metadata.APIBackendMetaData;
|
||||||
import com.kingsrook.qqq.backend.module.api.model.metadata.APITableBackendDetails;
|
import com.kingsrook.qqq.backend.module.api.model.metadata.APITableBackendDetails;
|
||||||
import org.apache.http.HttpEntity;
|
import org.apache.http.HttpEntity;
|
||||||
@ -101,7 +103,7 @@ public class BaseAPIActionUtil
|
|||||||
** method to build up a query string based on a given QFilter object
|
** method to build up a query string based on a given QFilter object
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
protected String buildQueryString(QQueryFilter filter, Integer limit, Integer skip, Map<String, QFieldMetaData> fields) throws QException
|
protected String buildQueryStringForGet(QQueryFilter filter, Integer limit, Integer skip, Map<String, QFieldMetaData> fields) throws QException
|
||||||
{
|
{
|
||||||
// todo: reasonable default action
|
// todo: reasonable default action
|
||||||
return (null);
|
return (null);
|
||||||
@ -109,6 +111,19 @@ public class BaseAPIActionUtil
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Do a default query string for a single-record GET - e.g., a query for just 1 record.
|
||||||
|
*******************************************************************************/
|
||||||
|
public String buildUrlSuffixForSingleRecordGet(Serializable primaryKey) throws QException
|
||||||
|
{
|
||||||
|
QTableMetaData table = actionInput.getTable();
|
||||||
|
QQueryFilter filter = new QQueryFilter()
|
||||||
|
.withCriteria(new QFilterCriteria(table.getPrimaryKeyField(), QCriteriaOperator.EQUALS, List.of(primaryKey)));
|
||||||
|
return (buildQueryStringForGet(filter, 1, 0, table.getFields()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** As part of making a request - set up its authorization header (not just
|
** As part of making a request - set up its authorization header (not just
|
||||||
** strictly "Authorization", but whatever is needed for auth).
|
** strictly "Authorization", but whatever is needed for auth).
|
||||||
@ -308,14 +323,7 @@ public class BaseAPIActionUtil
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
protected QRecord processPostResponse(QTableMetaData table, QRecord record, HttpResponse response) throws IOException
|
protected QRecord processPostResponse(QTableMetaData table, QRecord record, HttpResponse response) throws IOException
|
||||||
{
|
{
|
||||||
int statusCode = response.getStatusLine().getStatusCode();
|
JSONObject jsonObject = getJsonObject(response);
|
||||||
LOG.debug(statusCode);
|
|
||||||
|
|
||||||
HttpEntity entity = response.getEntity();
|
|
||||||
String resultString = EntityUtils.toString(entity);
|
|
||||||
LOG.debug(resultString);
|
|
||||||
|
|
||||||
JSONObject jsonObject = JsonUtils.toJSONObject(resultString);
|
|
||||||
|
|
||||||
String primaryKeyFieldName = table.getPrimaryKeyField();
|
String primaryKeyFieldName = table.getPrimaryKeyField();
|
||||||
String primaryKeyBackendName = getFieldBackendName(table.getField(primaryKeyFieldName));
|
String primaryKeyBackendName = getFieldBackendName(table.getField(primaryKeyFieldName));
|
||||||
@ -346,6 +354,24 @@ public class BaseAPIActionUtil
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
private JSONObject getJsonObject(HttpResponse response) throws IOException
|
||||||
|
{
|
||||||
|
int statusCode = response.getStatusLine().getStatusCode();
|
||||||
|
LOG.debug(statusCode);
|
||||||
|
|
||||||
|
HttpEntity entity = response.getEntity();
|
||||||
|
String resultString = EntityUtils.toString(entity);
|
||||||
|
LOG.debug(resultString);
|
||||||
|
|
||||||
|
JSONObject jsonObject = JsonUtils.toJSONObject(resultString);
|
||||||
|
return jsonObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@ -418,8 +444,18 @@ public class BaseAPIActionUtil
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
protected String urlEncode(String s)
|
protected String urlEncode(Serializable s)
|
||||||
{
|
{
|
||||||
return (URLEncoder.encode(s, StandardCharsets.UTF_8));
|
return (URLEncoder.encode(ValueUtils.getValueAsString(s), StandardCharsets.UTF_8));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public QRecord processSingleRecordGetResponse(QTableMetaData table, HttpResponse response) throws IOException
|
||||||
|
{
|
||||||
|
return (jsonObjectToRecord(getJsonObject(response), table.getFields()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,7 @@ import com.kingsrook.qqq.backend.core.actions.metadata.TableMetaDataAction;
|
|||||||
import com.kingsrook.qqq.backend.core.actions.reporting.ExportAction;
|
import com.kingsrook.qqq.backend.core.actions.reporting.ExportAction;
|
||||||
import com.kingsrook.qqq.backend.core.actions.tables.CountAction;
|
import com.kingsrook.qqq.backend.core.actions.tables.CountAction;
|
||||||
import com.kingsrook.qqq.backend.core.actions.tables.DeleteAction;
|
import com.kingsrook.qqq.backend.core.actions.tables.DeleteAction;
|
||||||
|
import com.kingsrook.qqq.backend.core.actions.tables.GetAction;
|
||||||
import com.kingsrook.qqq.backend.core.actions.tables.InsertAction;
|
import com.kingsrook.qqq.backend.core.actions.tables.InsertAction;
|
||||||
import com.kingsrook.qqq.backend.core.actions.tables.QueryAction;
|
import com.kingsrook.qqq.backend.core.actions.tables.QueryAction;
|
||||||
import com.kingsrook.qqq.backend.core.actions.tables.UpdateAction;
|
import com.kingsrook.qqq.backend.core.actions.tables.UpdateAction;
|
||||||
@ -69,10 +70,10 @@ import com.kingsrook.qqq.backend.core.model.actions.tables.count.CountInput;
|
|||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.count.CountOutput;
|
import com.kingsrook.qqq.backend.core.model.actions.tables.count.CountOutput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.delete.DeleteInput;
|
import com.kingsrook.qqq.backend.core.model.actions.tables.delete.DeleteInput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.delete.DeleteOutput;
|
import com.kingsrook.qqq.backend.core.model.actions.tables.delete.DeleteOutput;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.actions.tables.get.GetInput;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.actions.tables.get.GetOutput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.insert.InsertInput;
|
import com.kingsrook.qqq.backend.core.model.actions.tables.insert.InsertInput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.insert.InsertOutput;
|
import com.kingsrook.qqq.backend.core.model.actions.tables.insert.InsertOutput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterCriteria;
|
|
||||||
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.QueryInput;
|
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryInput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryOutput;
|
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryOutput;
|
||||||
@ -501,38 +502,31 @@ public class QJavalinImplementation
|
|||||||
String tableName = context.pathParam("table");
|
String tableName = context.pathParam("table");
|
||||||
QTableMetaData table = qInstance.getTable(tableName);
|
QTableMetaData table = qInstance.getTable(tableName);
|
||||||
String primaryKey = context.pathParam("primaryKey");
|
String primaryKey = context.pathParam("primaryKey");
|
||||||
QueryInput queryInput = new QueryInput(qInstance);
|
GetInput getInput = new GetInput(qInstance);
|
||||||
|
|
||||||
setupSession(context, queryInput);
|
setupSession(context, getInput);
|
||||||
queryInput.setTableName(tableName);
|
getInput.setTableName(tableName);
|
||||||
queryInput.setShouldGenerateDisplayValues(true);
|
getInput.setShouldGenerateDisplayValues(true);
|
||||||
queryInput.setShouldTranslatePossibleValues(true);
|
getInput.setShouldTranslatePossibleValues(true);
|
||||||
|
|
||||||
// todo - validate that the primary key is of the proper type (e.g,. not a string for an id field)
|
// todo - validate that the primary key is of the proper type (e.g,. not a string for an id field)
|
||||||
// and throw a 400-series error (tell the user bad-request), rather than, we're doing a 500 (server error)
|
// and throw a 400-series error (tell the user bad-request), rather than, we're doing a 500 (server error)
|
||||||
|
|
||||||
///////////////////////////////////////////////////////
|
getInput.setPrimaryKey(primaryKey);
|
||||||
// setup a filter for the primaryKey = the path-pram //
|
|
||||||
///////////////////////////////////////////////////////
|
|
||||||
queryInput.setFilter(new QQueryFilter()
|
|
||||||
.withCriteria(new QFilterCriteria()
|
|
||||||
.withFieldName(table.getPrimaryKeyField())
|
|
||||||
.withOperator(QCriteriaOperator.EQUALS)
|
|
||||||
.withValues(List.of(primaryKey))));
|
|
||||||
|
|
||||||
QueryAction queryAction = new QueryAction();
|
GetAction getAction = new GetAction();
|
||||||
QueryOutput queryOutput = queryAction.execute(queryInput);
|
GetOutput getOutput = getAction.execute(getInput);
|
||||||
|
|
||||||
///////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////
|
||||||
// throw a not found error if the record isn't found //
|
// throw a not found error if the record isn't found //
|
||||||
///////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////
|
||||||
if(queryOutput.getRecords().isEmpty())
|
if(getOutput.getRecord() == null)
|
||||||
{
|
{
|
||||||
throw (new QNotFoundException("Could not find " + table.getLabel() + " with "
|
throw (new QNotFoundException("Could not find " + table.getLabel() + " with "
|
||||||
+ table.getFields().get(table.getPrimaryKeyField()).getLabel() + " of " + primaryKey));
|
+ table.getFields().get(table.getPrimaryKeyField()).getLabel() + " of " + primaryKey));
|
||||||
}
|
}
|
||||||
|
|
||||||
context.result(JsonUtils.toJson(queryOutput.getRecords().get(0)));
|
context.result(JsonUtils.toJson(getOutput.getRecord()));
|
||||||
}
|
}
|
||||||
catch(Exception e)
|
catch(Exception e)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user