1717import static org .sagebionetworks .repo .model .query .jdo .SqlConstants .COL_NODE_PARENT_ID ;
1818import static org .sagebionetworks .repo .model .query .jdo .SqlConstants .COL_NODE_TYPE ;
1919import static org .sagebionetworks .repo .model .query .jdo .SqlConstants .COL_REVISION_FILE_HANDLE_ID ;
20- import static org .sagebionetworks .repo .model .query .jdo .SqlConstants .COL_REVISION_NUMBER ;
2120import static org .sagebionetworks .repo .model .query .jdo .SqlConstants .COL_REVISION_ITEMS ;
21+ import static org .sagebionetworks .repo .model .query .jdo .SqlConstants .COL_REVISION_NUMBER ;
2222import static org .sagebionetworks .repo .model .query .jdo .SqlConstants .COL_REVISION_OWNER_NODE ;
2323import static org .sagebionetworks .repo .model .query .jdo .SqlConstants .COL_REVISION_USER_ANNOS_JSON ;
2424import static org .sagebionetworks .repo .model .query .jdo .SqlConstants .TABLE_DERIVED_ANNOTATIONS ;
5252import org .sagebionetworks .repo .model .dao .FileHandleMetadataType ;
5353import org .sagebionetworks .repo .model .dbo .DDLUtilsImpl ;
5454import org .sagebionetworks .repo .model .download .ActionRequiredCount ;
55+ import org .sagebionetworks .repo .model .download .AddToDownloadListStatsResponse ;
5556import org .sagebionetworks .repo .model .download .AvailableFilter ;
5657import org .sagebionetworks .repo .model .download .DownloadListItem ;
5758import org .sagebionetworks .repo .model .download .DownloadListItemResult ;
@@ -95,6 +96,9 @@ public class DownloadListDAOImpl implements DownloadListDAO {
9596
9697 public static final String TEMP_ACTION_REQUIRED_TEMPLATE = DDLUtilsImpl
9798 .loadSQLFromClasspath ("sql/TempActionRequired-ddl.sql" );
99+
100+ public static final String GET_DATASET_COLLECTION_FILE_STATS = DDLUtilsImpl
101+ .loadSQLFromClasspath ("sql/GetDatasetFileStats.sql" );
98102
99103 private static final int BATCH_SIZE = 10000 ;
100104
@@ -647,11 +651,33 @@ public Long addChildrenToDownloadList(Long userId, Long parentId, boolean useVer
647651 return (long ) jdbcTemplate .update (sql , userId , parentId , limit );
648652 }
649653
654+ @ Override
655+ public AddToDownloadListStatsResponse getAddChildrenToDownloadListStats (Long parentId ) {
656+ List <String > fileTypeNames = EntityTypeUtils .getFileTypes ().stream ().map (EntityType ::name ).collect (Collectors .toList ());
657+
658+ String sql = "SELECT COUNT(N." + COL_NODE_ID + ") AS count, COALESCE(SUM(F." + COL_FILES_CONTENT_SIZE + "), 0) as size "
659+ + "FROM " + TABLE_NODE + " N "
660+ + "JOIN " + TABLE_REVISION + " R ON (N." + COL_NODE_ID + "=R." + COL_REVISION_OWNER_NODE + " AND N." + COL_NODE_CURRENT_REV + "=R." + COL_REVISION_NUMBER + ") "
661+ + "JOIN " + TABLE_FILES + " F ON (R." + COL_REVISION_FILE_HANDLE_ID + "=F." + COL_FILES_ID + ")"
662+ + "WHERE N." + COL_NODE_PARENT_ID + " = ? AND N."
663+ + COL_NODE_TYPE + " IN ('" + String .join ("','" , fileTypeNames ) + "')" ;
664+
665+ return jdbcTemplate .queryForObject (sql , (rs , i ) ->
666+ new AddToDownloadListStatsResponse ()
667+ .setFileCount (rs .getLong ("count" ))
668+ .setFileSize (rs .getLong ("size" ))
669+ .setIsFileCountAndSizeEstimate (false )
670+ , parentId );
671+
672+ }
673+
650674 @ WriteTransaction
651675 @ Override
652676 public Long addDescendantsToDownloadList (Long userId , Long parentId , boolean useVersion , long limit ) {
653677 String versionString = useVersion ? "N." + COL_NODE_CURRENT_REV : "-1" ;
654678
679+ List <String > fileTypeNames = EntityTypeUtils .getFileTypes ().stream ().map (EntityType ::name ).collect (Collectors .toList ());
680+
655681 String sql = String .format ("INSERT IGNORE INTO " + TABLE_DOWNLOAD_LIST_ITEM_V2 + " ("
656682 + COL_DOWNLOAD_LIST_ITEM_V2_PRINCIPAL_ID + ","
657683 + COL_DOWNLOAD_LIST_ITEM_V2_ENTITY_ID + ","
@@ -662,13 +688,37 @@ public Long addDescendantsToDownloadList(Long userId, Long parentId, boolean use
662688 + " UNION DISTINCT"
663689 + " SELECT N." + COL_NODE_ID + ", CONTAINERS.DIST + 1 FROM CONTAINERS JOIN " + TABLE_NODE + " AS N ON (CONTAINERS.ID = N." + COL_NODE_PARENT_ID + " AND N." +COL_NODE_TYPE + " IN ('project', 'folder'))"
664690 + ") "
665- + "SELECT ?, N." + COL_NODE_ID + ", %s, NOW(3) FROM " + TABLE_NODE + " N JOIN CONTAINERS ON (N." + COL_NODE_PARENT_ID + " = CONTAINERS.ID AND N." + COL_NODE_TYPE + "= 'file' ) "
691+ + "SELECT ?, N." + COL_NODE_ID + ", %s, NOW(3) FROM " + TABLE_NODE + " N JOIN CONTAINERS ON (N." + COL_NODE_PARENT_ID + " = CONTAINERS.ID AND N." + COL_NODE_TYPE + " IN ('" + String . join ( "','" , fileTypeNames ) + "') ) "
666692 + "ORDER BY CONTAINERS.DIST, CONTAINERS.ID, N." + COL_NODE_ID + " LIMIT ?" , versionString );
667693
668694 createOrUpdateDownloadList (userId );
669695
670696 return (long ) jdbcTemplate .update (sql , parentId , userId , limit );
671697 }
698+
699+ @ Override
700+ public AddToDownloadListStatsResponse getAddDescendantsToDownloadListStats (Long parentId , int maxContainers ) {
701+
702+ List <String > fileTypeNames = EntityTypeUtils .getFileTypes ().stream ().map (EntityType ::name ).collect (Collectors .toList ());
703+
704+ String sql = "WITH RECURSIVE CONTAINERS (ID, DIST) AS ("
705+ + " SELECT " + COL_NODE_ID + ", 0 FROM " + TABLE_NODE + " WHERE " + COL_NODE_ID + "=? AND " + COL_NODE_TYPE + " IN ('project', 'folder')"
706+ + " UNION ALL"
707+ + " SELECT N." + COL_NODE_ID + ", CONTAINERS.DIST + 1 FROM CONTAINERS JOIN " + TABLE_NODE + " AS N ON (CONTAINERS.ID = N." + COL_NODE_PARENT_ID + " AND N." +COL_NODE_TYPE + " IN ('project', 'folder'))"
708+ // We limit the number of containers that we do the computation against to avoid overloading the database
709+ + " LIMIT ?)"
710+ + "SELECT COUNT(N." + COL_NODE_ID + ") AS count, COALESCE(SUM(F." + COL_FILES_CONTENT_SIZE + "), 0) as size, (SELECT COUNT(ID) FROM CONTAINERS) >= ? as isEstimate "
711+ + "FROM CONTAINERS "
712+ + "JOIN " + TABLE_NODE + " N ON (N." + COL_NODE_PARENT_ID + " = CONTAINERS.ID AND N." + COL_NODE_TYPE + " IN ('" + String .join ("','" , fileTypeNames ) + "')) "
713+ + "JOIN " + TABLE_REVISION + " R ON (N." + COL_NODE_ID + "=R." + COL_REVISION_OWNER_NODE + " AND N." + COL_NODE_CURRENT_REV + "=R." + COL_REVISION_NUMBER + ") "
714+ + "JOIN " + TABLE_FILES + " F ON (R." + COL_REVISION_FILE_HANDLE_ID + "=F." + COL_FILES_ID + ")" ;
715+
716+ return jdbcTemplate .queryForObject (sql , (rs , i ) -> new AddToDownloadListStatsResponse ()
717+ .setFileCount (rs .getLong ("count" ))
718+ .setFileSize (rs .getLong ("size" ))
719+ .setIsFileCountAndSizeEstimate (rs .getBoolean ("isEstimate" ))
720+ , parentId , maxContainers , maxContainers );
721+ }
672722
673723 @ Override
674724 public JSONObject getItemManifestDetails (DownloadListItem item ) {
@@ -721,6 +771,29 @@ public int getBatchSize() {
721771 return (long )IntStream .of (updates ).sum ();
722772 }
723773
774+ @ Override
775+ public AddToDownloadListStatsResponse getAddFileEntityRefToDownloadListStats (List <EntityRef > fileRefs ) {
776+ String sql = "SELECT COUNT(R." + COL_REVISION_OWNER_NODE + ") AS count, SUM(F." + COL_FILES_CONTENT_SIZE + ") as size "
777+ + "FROM " + TABLE_REVISION + " R "
778+ + "JOIN " + TABLE_FILES + " F ON (R." + COL_REVISION_FILE_HANDLE_ID + "=F." + COL_FILES_ID + ") "
779+ + "WHERE (R." + COL_REVISION_OWNER_NODE + ", R." + COL_REVISION_NUMBER + ") IN (:fileRefs)" ;
780+
781+ List <Long []> fileRefsParam = fileRefs .stream ().map ( fileRef -> new Long [] {
782+ KeyFactory .stringToKey (fileRef .getEntityId ()), fileRef .getVersionNumber ()
783+ }).collect (Collectors .toList ());
784+
785+ Map <String , ?> params = Map .of (
786+ "fileRefs" , fileRefsParam
787+ );
788+
789+ return namedJdbcTemplate .queryForObject (sql , params , (rs , i ) ->
790+ new AddToDownloadListStatsResponse ()
791+ .setFileCount (rs .getLong ("count" ))
792+ .setFileSize (rs .getLong ("size" ))
793+ .setIsFileCountAndSizeEstimate (false )
794+ );
795+ }
796+
724797 @ Override
725798 @ WriteTransaction
726799 public Long addDatasetEntityRefFilesToDownloadList (Long userId , List <EntityRef > datasetRefs , long limit ) {
@@ -762,4 +835,26 @@ public Long addDatasetEntityRefFilesToDownloadList(Long userId, List<EntityRef>
762835 return (long ) namedJdbcTemplate .update (sql , params );
763836 }
764837
838+ @ Override
839+ public AddToDownloadListStatsResponse getAddDatasetEntityRefFilesToDownloadListStats (List <EntityRef > datasetRefs ) {
840+
841+ List <Long []> datasetParam = datasetRefs
842+ .stream ()
843+ .map ( dataset -> new Long [] {
844+ KeyFactory .stringToKey (dataset .getEntityId ()), dataset .getVersionNumber ()
845+ })
846+ .collect (Collectors .toList ());
847+
848+ Map <String , ?> params = Map .of (
849+ "datasetRefs" , datasetParam
850+ );
851+
852+ return namedJdbcTemplate .queryForObject (GET_DATASET_COLLECTION_FILE_STATS , params , (rs , i ) ->
853+ new AddToDownloadListStatsResponse ()
854+ .setFileCount (rs .getLong ("count" ))
855+ .setFileSize (rs .getLong ("size" ))
856+ .setIsFileCountAndSizeEstimate (false )
857+ );
858+ }
859+
765860}
0 commit comments