Skip to content

Commit 06a2c1a

Browse files
authored
Merge pull request #904 from amvanbaren/batch-file-urls
Get file urls in one query
2 parents a3afd3b + 79cf222 commit 06a2c1a

File tree

8 files changed

+170
-49
lines changed

8 files changed

+170
-49
lines changed

server/src/main/java/org/eclipse/openvsx/LocalRegistryService.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,8 @@ public VersionReferencesJson getVersionReferences(String namespace, String exten
149149
? repositories.findActiveVersionsSorted(namespace, extension, pageRequest)
150150
: repositories.findActiveVersionsSorted(namespace, extension, targetPlatform, pageRequest);
151151

152+
var fileUrls = storageUtil.getFileUrls(page.getContent(), UrlUtil.getBaseUrl(), withFileTypes(DOWNLOAD));
153+
152154
var json = new VersionReferencesJson();
153155
json.offset = (int) page.getPageable().getOffset();
154156
json.totalSize = (int) page.getTotalElements();
@@ -159,7 +161,7 @@ public VersionReferencesJson getVersionReferences(String namespace, String exten
159161
versionRef.targetPlatform = extVersion.getTargetPlatform();
160162
versionRef.engines = extVersion.getEnginesMap();
161163
versionRef.url = UrlUtil.createApiVersionUrl(UrlUtil.getBaseUrl(), extVersion);
162-
versionRef.files = storageUtil.getFileUrls(extVersion, UrlUtil.getBaseUrl(), withFileTypes(DOWNLOAD));
164+
versionRef.files = fileUrls.get(extVersion.getId());
163165
if(versionRef.files.containsKey(DOWNLOAD_SIG)) {
164166
versionRef.files.put(PUBLIC_KEY, UrlUtil.getPublicKeyUrl(extVersion));
165167
}
@@ -396,11 +398,13 @@ public NamespaceDetailsJson getNamespaceDetails(String namespaceName) {
396398
: null;
397399

398400
var serverUrl = UrlUtil.getBaseUrl();
399-
json.extensions = repositories.findLatestVersions(namespace).stream()
401+
var extVersions = repositories.findLatestVersions(namespace);
402+
var fileUrls = storageUtil.getFileUrls(extVersions, serverUrl, withFileTypes(DOWNLOAD, ICON));
403+
json.extensions = extVersions.stream()
400404
.map(extVersion -> {
401405
var entry = extVersion.toSearchEntryJson();
402406
entry.url = createApiUrl(serverUrl, "api", entry.namespace, entry.name);
403-
entry.files = storageUtil.getFileUrls(extVersion, serverUrl, withFileTypes(DOWNLOAD, ICON));
407+
entry.files = fileUrls.get(extVersion.getId());
404408
if(entry.files.containsKey(DOWNLOAD_SIG)) {
405409
entry.files.put(PUBLIC_KEY, UrlUtil.getPublicKeyUrl(extVersion));
406410
}

server/src/main/java/org/eclipse/openvsx/UserAPI.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -187,15 +187,15 @@ public List<ExtensionJson> getOwnExtensions() {
187187
throw new ResponseStatusException(HttpStatus.FORBIDDEN);
188188
}
189189

190+
var extVersions = repositories.findLatestVersions(user);
190191
var types = new String[]{ DOWNLOAD, MANIFEST, ICON, README, LICENSE, CHANGELOG, VSIXMANIFEST };
191-
return repositories.findExtensions(user)
192-
.map(e -> repositories.findLatestVersion(e, null, false, false))
192+
var fileUrls = storageUtil.getFileUrls(extVersions, UrlUtil.getBaseUrl(), types);
193+
return extVersions.stream()
193194
.map(latest -> {
194195
var json = latest.toExtensionJson();
195196
json.preview = latest.isPreview();
196197
json.active = latest.getExtension().isActive();
197-
json.files = storageUtil.getFileUrls(latest, UrlUtil.getBaseUrl(), types);
198-
198+
json.files = fileUrls.get(latest.getId());
199199
return json;
200200
})
201201
.toList();

server/src/main/java/org/eclipse/openvsx/admin/AdminService.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -263,14 +263,15 @@ public UserPublishInfoJson getUserPublishInfo(String provider, String loginName)
263263
userPublishInfo.user = user.toUserJson();
264264
eclipse.enrichUserJson(userPublishInfo.user, user);
265265
userPublishInfo.activeAccessTokenNum = (int) repositories.countActiveAccessTokens(user);
266-
userPublishInfo.extensions = repositories.findExtensions(user).stream()
267-
.map(e -> repositories.findLatestVersion(e, null, false, false))
266+
var extVersions = repositories.findLatestVersions(user);
267+
var types = new String[]{DOWNLOAD, MANIFEST, ICON, README, LICENSE, CHANGELOG, VSIXMANIFEST};
268+
var fileUrls = storageUtil.getFileUrls(extVersions, UrlUtil.getBaseUrl(), types);
269+
userPublishInfo.extensions = extVersions.stream()
268270
.map(latest -> {
269271
var json = latest.toExtensionJson();
270272
json.preview = latest.isPreview();
271273
json.active = latest.getExtension().isActive();
272-
json.files = storageUtil.getFileUrls(latest, UrlUtil.getBaseUrl(),
273-
DOWNLOAD, MANIFEST, ICON, README, LICENSE, CHANGELOG, VSIXMANIFEST);
274+
json.files = fileUrls.get(latest.getId());
274275

275276
return json;
276277
})

server/src/main/java/org/eclipse/openvsx/repositories/ExtensionVersionJooqRepository.java

Lines changed: 148 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -449,16 +449,24 @@ private List<ExtensionVersion> fetch(SelectQuery<Record> query) {
449449
}
450450

451451
private ExtensionVersion toExtensionVersionFull(Record record) {
452-
return toExtensionVersionFull(record, null);
452+
return toExtensionVersionFull(record, null, null);
453453
}
454454

455-
private ExtensionVersion toExtensionVersionFull(Record record, Extension extension) {
456-
var extVersion = toExtensionVersionCommon(record, extension);
457-
extVersion.setLicense(record.get(EXTENSION_VERSION.LICENSE));
458-
extVersion.setHomepage(record.get(EXTENSION_VERSION.HOMEPAGE));
459-
extVersion.setBugs(record.get(EXTENSION_VERSION.BUGS));
460-
extVersion.setMarkdown(record.get(EXTENSION_VERSION.MARKDOWN));
461-
extVersion.setQna(record.get(EXTENSION_VERSION.QNA));
455+
private ExtensionVersion toExtensionVersionFull(
456+
Record record,
457+
Extension extension,
458+
FieldMapper extensionVersionMapper
459+
) {
460+
if(extensionVersionMapper == null) {
461+
extensionVersionMapper = new DefaultFieldMapper();
462+
}
463+
464+
var extVersion = toExtensionVersionCommon(record, extension, extensionVersionMapper);
465+
extVersion.setLicense(record.get(extensionVersionMapper.map(EXTENSION_VERSION.LICENSE)));
466+
extVersion.setHomepage(record.get(extensionVersionMapper.map(EXTENSION_VERSION.HOMEPAGE)));
467+
extVersion.setBugs(record.get(extensionVersionMapper.map(EXTENSION_VERSION.BUGS)));
468+
extVersion.setMarkdown(record.get(extensionVersionMapper.map(EXTENSION_VERSION.MARKDOWN)));
469+
extVersion.setQna(record.get(extensionVersionMapper.map(EXTENSION_VERSION.QNA)));
462470

463471
if(extension == null) {
464472
var newExtension = extVersion.getExtension();
@@ -490,34 +498,38 @@ private ExtensionVersion toExtensionVersionFull(Record record, Extension extensi
490498
}
491499

492500
private ExtensionVersion toExtensionVersion(Record record) {
493-
var extVersion = toExtensionVersionCommon(record, null);
501+
var extVersion = toExtensionVersionCommon(record, null, new DefaultFieldMapper());
494502
extVersion.setType(ExtensionVersion.Type.MINIMAL);
495503
return extVersion;
496504
}
497505

498-
private ExtensionVersion toExtensionVersionCommon(Record record, Extension extension) {
506+
private ExtensionVersion toExtensionVersionCommon(
507+
Record record,
508+
Extension extension,
509+
FieldMapper extensionVersionMapper
510+
) {
499511
var converter = new ListOfStringConverter();
500512

501513
var extVersion = new ExtensionVersion();
502-
extVersion.setId(record.get(EXTENSION_VERSION.ID));
503-
extVersion.setVersion(record.get(EXTENSION_VERSION.VERSION));
504-
extVersion.setTargetPlatform(record.get(EXTENSION_VERSION.TARGET_PLATFORM));
505-
extVersion.setPreview(record.get(EXTENSION_VERSION.PREVIEW));
506-
extVersion.setPreRelease(record.get(EXTENSION_VERSION.PRE_RELEASE));
507-
extVersion.setTimestamp(record.get(EXTENSION_VERSION.TIMESTAMP));
508-
extVersion.setDisplayName(record.get(EXTENSION_VERSION.DISPLAY_NAME));
509-
extVersion.setDescription(record.get(EXTENSION_VERSION.DESCRIPTION));
510-
extVersion.setEngines(toList(record.get(EXTENSION_VERSION.ENGINES), converter));
511-
extVersion.setCategories(toList(record.get(EXTENSION_VERSION.CATEGORIES), converter));
512-
extVersion.setTags(toList(record.get(EXTENSION_VERSION.TAGS), converter));
513-
extVersion.setExtensionKind(toList(record.get(EXTENSION_VERSION.EXTENSION_KIND), converter));
514-
extVersion.setRepository(record.get(EXTENSION_VERSION.REPOSITORY));
515-
extVersion.setGalleryColor(record.get(EXTENSION_VERSION.GALLERY_COLOR));
516-
extVersion.setGalleryTheme(record.get(EXTENSION_VERSION.GALLERY_THEME));
517-
extVersion.setLocalizedLanguages(toList(record.get(EXTENSION_VERSION.LOCALIZED_LANGUAGES), converter));
518-
extVersion.setDependencies(toList(record.get(EXTENSION_VERSION.DEPENDENCIES), converter));
519-
extVersion.setBundledExtensions(toList(record.get(EXTENSION_VERSION.BUNDLED_EXTENSIONS), converter));
520-
extVersion.setSponsorLink(record.get(EXTENSION_VERSION.SPONSOR_LINK));
514+
extVersion.setId(record.get(extensionVersionMapper.map(EXTENSION_VERSION.ID)));
515+
extVersion.setVersion(record.get(extensionVersionMapper.map(EXTENSION_VERSION.VERSION)));
516+
extVersion.setTargetPlatform(record.get(extensionVersionMapper.map(EXTENSION_VERSION.TARGET_PLATFORM)));
517+
extVersion.setPreview(record.get(extensionVersionMapper.map(EXTENSION_VERSION.PREVIEW)));
518+
extVersion.setPreRelease(record.get(extensionVersionMapper.map(EXTENSION_VERSION.PRE_RELEASE)));
519+
extVersion.setTimestamp(record.get(extensionVersionMapper.map(EXTENSION_VERSION.TIMESTAMP)));
520+
extVersion.setDisplayName(record.get(extensionVersionMapper.map(EXTENSION_VERSION.DISPLAY_NAME)));
521+
extVersion.setDescription(record.get(extensionVersionMapper.map(EXTENSION_VERSION.DESCRIPTION)));
522+
extVersion.setEngines(toList(record.get(extensionVersionMapper.map(EXTENSION_VERSION.ENGINES)), converter));
523+
extVersion.setCategories(toList(record.get(extensionVersionMapper.map(EXTENSION_VERSION.CATEGORIES)), converter));
524+
extVersion.setTags(toList(record.get(extensionVersionMapper.map(EXTENSION_VERSION.TAGS)), converter));
525+
extVersion.setExtensionKind(toList(record.get(extensionVersionMapper.map(EXTENSION_VERSION.EXTENSION_KIND)), converter));
526+
extVersion.setRepository(record.get(extensionVersionMapper.map(EXTENSION_VERSION.REPOSITORY)));
527+
extVersion.setGalleryColor(record.get(extensionVersionMapper.map(EXTENSION_VERSION.GALLERY_COLOR)));
528+
extVersion.setGalleryTheme(record.get(extensionVersionMapper.map(EXTENSION_VERSION.GALLERY_THEME)));
529+
extVersion.setLocalizedLanguages(toList(record.get(extensionVersionMapper.map(EXTENSION_VERSION.LOCALIZED_LANGUAGES)), converter));
530+
extVersion.setDependencies(toList(record.get(extensionVersionMapper.map(EXTENSION_VERSION.DEPENDENCIES)), converter));
531+
extVersion.setBundledExtensions(toList(record.get(extensionVersionMapper.map(EXTENSION_VERSION.BUNDLED_EXTENSIONS)), converter));
532+
extVersion.setSponsorLink(record.get(extensionVersionMapper.map(EXTENSION_VERSION.SPONSOR_LINK)));
521533

522534
if(extension == null) {
523535
var namespace = new Namespace();
@@ -653,7 +665,7 @@ public ExtensionVersion findLatest(
653665
query.addJoin(USER_DATA, USER_DATA.ID.eq(PERSONAL_ACCESS_TOKEN.USER_DATA));
654666
query.addJoin(SIGNATURE_KEY_PAIR, JoinType.LEFT_OUTER_JOIN, SIGNATURE_KEY_PAIR.ID.eq(EXTENSION_VERSION.SIGNATURE_KEY_PAIR_ID));
655667
query.addConditions(EXTENSION_VERSION.EXTENSION_ID.eq(extension.getId()));
656-
return query.fetchOne((record) -> toExtensionVersionFull(record, extension));
668+
return query.fetchOne((record) -> toExtensionVersionFull(record, extension, null));
657669
}
658670

659671
public List<ExtensionVersion> findLatest(Namespace namespace) {
@@ -716,6 +728,96 @@ public List<ExtensionVersion> findLatest(Namespace namespace) {
716728
});
717729
}
718730

731+
public List<ExtensionVersion> findLatest(UserData user) {
732+
var latestQuery = findLatestQuery(null, false, false);
733+
latestQuery.addSelect(
734+
EXTENSION_VERSION.ID,
735+
EXTENSION_VERSION.VERSION,
736+
EXTENSION_VERSION.TARGET_PLATFORM,
737+
EXTENSION_VERSION.PREVIEW,
738+
EXTENSION_VERSION.PRE_RELEASE,
739+
EXTENSION_VERSION.TIMESTAMP,
740+
EXTENSION_VERSION.DISPLAY_NAME,
741+
EXTENSION_VERSION.DESCRIPTION,
742+
EXTENSION_VERSION.ENGINES,
743+
EXTENSION_VERSION.CATEGORIES,
744+
EXTENSION_VERSION.TAGS,
745+
EXTENSION_VERSION.EXTENSION_KIND,
746+
EXTENSION_VERSION.LICENSE,
747+
EXTENSION_VERSION.HOMEPAGE,
748+
EXTENSION_VERSION.REPOSITORY,
749+
EXTENSION_VERSION.SPONSOR_LINK,
750+
EXTENSION_VERSION.BUGS,
751+
EXTENSION_VERSION.MARKDOWN,
752+
EXTENSION_VERSION.GALLERY_COLOR,
753+
EXTENSION_VERSION.GALLERY_THEME,
754+
EXTENSION_VERSION.LOCALIZED_LANGUAGES,
755+
EXTENSION_VERSION.QNA,
756+
EXTENSION_VERSION.DEPENDENCIES,
757+
EXTENSION_VERSION.BUNDLED_EXTENSIONS,
758+
EXTENSION_VERSION.SIGNATURE_KEY_PAIR_ID,
759+
EXTENSION_VERSION.PUBLISHED_WITH_ID
760+
);
761+
latestQuery.addConditions(EXTENSION_VERSION.EXTENSION_ID.eq(EXTENSION.ID));
762+
var latest = latestQuery.asTable();
763+
764+
var query = dsl.selectQuery();
765+
query.addSelect(
766+
NAMESPACE.ID,
767+
NAMESPACE.NAME,
768+
NAMESPACE.DISPLAY_NAME,
769+
NAMESPACE.PUBLIC_ID,
770+
EXTENSION.ID,
771+
EXTENSION.NAME,
772+
EXTENSION.PUBLIC_ID,
773+
EXTENSION.AVERAGE_RATING,
774+
EXTENSION.REVIEW_COUNT,
775+
EXTENSION.DOWNLOAD_COUNT,
776+
EXTENSION.PUBLISHED_DATE,
777+
EXTENSION.LAST_UPDATED_DATE,
778+
latest.field(EXTENSION_VERSION.ID),
779+
latest.field(EXTENSION_VERSION.VERSION),
780+
latest.field(EXTENSION_VERSION.TARGET_PLATFORM),
781+
latest.field(EXTENSION_VERSION.PREVIEW),
782+
latest.field(EXTENSION_VERSION.PRE_RELEASE),
783+
latest.field(EXTENSION_VERSION.TIMESTAMP),
784+
latest.field(EXTENSION_VERSION.DISPLAY_NAME),
785+
latest.field(EXTENSION_VERSION.DESCRIPTION),
786+
latest.field(EXTENSION_VERSION.ENGINES),
787+
latest.field(EXTENSION_VERSION.CATEGORIES),
788+
latest.field(EXTENSION_VERSION.TAGS),
789+
latest.field(EXTENSION_VERSION.EXTENSION_KIND),
790+
latest.field(EXTENSION_VERSION.LICENSE),
791+
latest.field(EXTENSION_VERSION.HOMEPAGE),
792+
latest.field(EXTENSION_VERSION.REPOSITORY),
793+
latest.field(EXTENSION_VERSION.SPONSOR_LINK),
794+
latest.field(EXTENSION_VERSION.BUGS),
795+
latest.field(EXTENSION_VERSION.MARKDOWN),
796+
latest.field(EXTENSION_VERSION.GALLERY_COLOR),
797+
latest.field(EXTENSION_VERSION.GALLERY_THEME),
798+
latest.field(EXTENSION_VERSION.LOCALIZED_LANGUAGES),
799+
latest.field(EXTENSION_VERSION.QNA),
800+
latest.field(EXTENSION_VERSION.DEPENDENCIES),
801+
latest.field(EXTENSION_VERSION.BUNDLED_EXTENSIONS),
802+
SIGNATURE_KEY_PAIR.PUBLIC_ID,
803+
USER_DATA.ID,
804+
USER_DATA.ROLE,
805+
USER_DATA.LOGIN_NAME,
806+
USER_DATA.FULL_NAME,
807+
USER_DATA.AVATAR_URL,
808+
USER_DATA.PROVIDER_URL,
809+
USER_DATA.PROVIDER
810+
);
811+
query.addFrom(NAMESPACE);
812+
query.addJoin(EXTENSION, EXTENSION.NAMESPACE_ID.eq(NAMESPACE.ID));
813+
query.addJoin(latest, JoinType.CROSS_APPLY, DSL.condition(true));
814+
query.addJoin(SIGNATURE_KEY_PAIR, JoinType.LEFT_OUTER_JOIN, SIGNATURE_KEY_PAIR.ID.eq(latest.field(EXTENSION_VERSION.SIGNATURE_KEY_PAIR_ID)));
815+
query.addJoin(PERSONAL_ACCESS_TOKEN, JoinType.LEFT_OUTER_JOIN, PERSONAL_ACCESS_TOKEN.ID.eq(latest.field(EXTENSION_VERSION.PUBLISHED_WITH_ID)));
816+
query.addJoin(USER_DATA, USER_DATA.ID.eq(PERSONAL_ACCESS_TOKEN.USER_DATA));
817+
query.addConditions(PERSONAL_ACCESS_TOKEN.USER_DATA.eq(user.getId()));
818+
return query.fetch(record -> toExtensionVersionFull(record, null, new TableFieldMapper(latest)));
819+
}
820+
719821
public ExtensionVersion findLatestForAllUrls(
720822
Extension extension,
721823
String targetPlatform,
@@ -849,4 +951,20 @@ public List<String> findDistinctTargetPlatforms(Extension extension) {
849951
.and(EXTENSION_VERSION.ACTIVE.eq(true))
850952
.fetch(EXTENSION_VERSION.TARGET_PLATFORM);
851953
}
954+
955+
private interface FieldMapper {
956+
<T> Field<T> map(Field<T> field);
957+
}
958+
959+
private record TableFieldMapper(Table<Record> table) implements FieldMapper {
960+
public <T> Field<T> map(Field<T> field) {
961+
return table.field(field);
962+
}
963+
}
964+
965+
private static class DefaultFieldMapper implements FieldMapper {
966+
public <T> Field<T> map(Field<T> field) {
967+
return field;
968+
}
969+
}
852970
}

server/src/main/java/org/eclipse/openvsx/repositories/RepositoryService.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,10 @@ public List<ExtensionVersion> findLatestVersions(Namespace namespace) {
552552
return extensionVersionJooqRepo.findLatest(namespace);
553553
}
554554

555+
public List<ExtensionVersion> findLatestVersions(UserData user) {
556+
return extensionVersionJooqRepo.findLatest(user);
557+
}
558+
555559
public List<String> findExtensionTargetPlatforms(Extension extension) {
556560
return extensionVersionJooqRepo.findDistinctTargetPlatforms(extension);
557561
}

server/src/main/java/org/eclipse/openvsx/storage/StorageUtilService.java

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -251,12 +251,6 @@ private String getFileUrl(String name, ExtensionVersion extVersion, String serve
251251
return UrlUtil.createApiFileUrl(serverUrl, extVersion, name);
252252
}
253253

254-
@Observed
255-
public Map<String, String> getFileUrls(ExtensionVersion extVersion, String serverUrl, String... types) {
256-
var fileUrls = getFileUrls(List.of(extVersion), serverUrl, types);
257-
return fileUrls.get(extVersion.getId());
258-
}
259-
260254
/**
261255
* Returns URLs for the given file types as a map of ExtensionVersion.id by a map of type by file URL, to be used in JSON response data.
262256
*/

server/src/test/java/org/eclipse/openvsx/admin/AdminAPITest.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -483,8 +483,7 @@ public void testGetUserPublishInfo() throws Exception {
483483

484484
Mockito.when(repositories.findUserByLoginName("github", "test")).thenReturn(user);
485485
Mockito.when(repositories.countActiveAccessTokens(user)).thenReturn(1L);
486-
Mockito.when(repositories.findExtensions(user))
487-
.thenReturn(Streamable.of(versions.get(0).getExtension()));
486+
Mockito.when(repositories.findLatestVersions(user)).thenReturn(versions);
488487

489488
mockMvc.perform(get("/admin/publisher/{provider}/{loginName}", "github", "test")
490489
.with(user("admin_user").authorities(new SimpleGrantedAuthority(("ROLE_ADMIN"))))

server/src/test/java/org/eclipse/openvsx/repositories/RepositoryServiceSmokeTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ void testExecuteQueries() {
201201
() -> repositories.findLatestVersionForAllUrls(extension, "targetPlatform", false, false),
202202
() -> repositories.findLatestVersion(extension, "targetPlatform", false, false),
203203
() -> repositories.findLatestVersions(namespace),
204+
() -> repositories.findLatestVersions(userData),
204205
() -> repositories.findExtensionTargetPlatforms(extension)
205206
);
206207

0 commit comments

Comments
 (0)