Update for use-case of Get - listing a single file - to pass that file name in, to avoid listing huge directory when not needed

This commit is contained in:
2025-04-08 13:35:08 -05:00
parent 64278e674b
commit 6f1e9413f6
3 changed files with 78 additions and 13 deletions

View File

@ -59,9 +59,11 @@ import com.kingsrook.qqq.backend.core.model.metadata.variants.BackendVariantSett
import com.kingsrook.qqq.backend.core.model.metadata.variants.BackendVariantsUtil;
import com.kingsrook.qqq.backend.core.model.statusmessages.SystemErrorStatusMessage;
import com.kingsrook.qqq.backend.core.modules.backend.implementations.utils.BackendQueryFilterUtils;
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
import com.kingsrook.qqq.backend.core.utils.ExceptionUtils;
import com.kingsrook.qqq.backend.core.utils.ObjectUtils;
import com.kingsrook.qqq.backend.core.utils.StringUtils;
import com.kingsrook.qqq.backend.core.utils.ValueUtils;
import com.kingsrook.qqq.backend.core.utils.lambdas.UnsafeSupplier;
import com.kingsrook.qqq.backend.module.filesystem.base.FilesystemRecordBackendDetailFields;
import com.kingsrook.qqq.backend.module.filesystem.base.model.metadata.AbstractFilesystemBackendMetaData;
@ -296,8 +298,23 @@ public abstract class AbstractBaseFilesystemAction<FILE>
QueryOutput queryOutput = new QueryOutput(queryInput);
String requestedPath = null;
List<FILE> files = listFiles(table, queryInput.getBackend(), requestedPath);
String requestedPath = null;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// if this is a query for a single file name, then get that file name in the requestedPath param for the listFiles call //
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
if(queryInput.getFilter() != null)
{
for(QFilterCriteria criteria : CollectionUtils.nonNullList(queryInput.getFilter().getCriteria()))
{
if(criteria.getFieldName().equals(tableDetails.getFileNameFieldName()) && criteria.getOperator().equals(QCriteriaOperator.EQUALS))
{
requestedPath = ValueUtils.getValueAsString(criteria.getValues().get(0));
}
}
}
List<FILE> files = listFiles(table, queryInput.getBackend(), requestedPath);
switch(tableDetails.getCardinality())
{

View File

@ -325,20 +325,51 @@ public class AbstractSFTPAction extends AbstractBaseFilesystemAction<SFTPDirEntr
fullPath = "." + fullPath;
}
for(SftpClient.DirEntry dirEntry : sftpClient.readDir(fullPath))
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// in case we were asked to list a single file name, make sure we don't put a slash on the end (which wouldn't be found) //
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
if(fullPath.endsWith("/"))
{
if(".".equals(dirEntry.getFilename()) || "..".equals(dirEntry.getFilename()))
{
continue;
}
fullPath = fullPath.substring(0, fullPath.length() - 1);
}
if(dirEntry.getAttributes().isDirectory())
{
// todo - recursive??
continue;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// make a 'stat' call, to find out if the path is found, and if it is, if it describes a single file, or a directory //
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
SftpClient.Attributes stat = sftpClient.stat(fullPath);
if(stat == null)
{
return (rs);
}
else if(stat.isRegularFile())
{
///////////////////////////////////////////////////////////////////////////
// split up the fullPath into its directory prefix, and file name suffix //
///////////////////////////////////////////////////////////////////////////
int lastSlashIndex = fullPath.lastIndexOf("/");
String directory = lastSlashIndex == -1 ? "./" : fullPath.substring(0, lastSlashIndex);
String fileBaseName = lastSlashIndex == -1 ? fullPath : fullPath.substring(lastSlashIndex + 1);
rs.add(new SFTPDirEntryWithPath(fullPath, dirEntry));
SftpClient.DirEntry dirEntry = new SftpClient.DirEntry(fileBaseName, fullPath, stat);
rs.add(new SFTPDirEntryWithPath(directory, dirEntry));
}
else if(stat.isDirectory())
{
for(SftpClient.DirEntry dirEntry : sftpClient.readEntries(fullPath))
{
if(".".equals(dirEntry.getFilename()) || "..".equals(dirEntry.getFilename()))
{
continue;
}
if(dirEntry.getAttributes().isDirectory())
{
// todo - recursive??
continue;
}
rs.add(new SFTPDirEntryWithPath(fullPath, dirEntry));
}
}
return (rs);

View File

@ -62,6 +62,23 @@ public class S3QueryActionTest extends BaseS3Test
/*******************************************************************************
**
*******************************************************************************/
@Test
public void testGet() throws QException
{
QueryInput queryInput = new QueryInput(TestUtils.TABLE_NAME_BLOB_S3)
.withFilter(new QQueryFilter(new QFilterCriteria("fileName", QCriteriaOperator.EQUALS, "BLOB-1.txt")));
S3QueryAction s3QueryAction = new S3QueryAction();
s3QueryAction.setS3Utils(getS3Utils());
QueryOutput queryOutput = s3QueryAction.execute(queryInput);
Assertions.assertEquals(1, queryOutput.getRecords().size(), "Expected # of rows from query");
}
/*******************************************************************************
**
*******************************************************************************/