Use DELETE statement instead of deleting one by one for HotRod store

Closes #9420
This commit is contained in:
Michal Hajas 2022-11-08 15:57:06 +01:00 committed by Hynek Mlnařík
parent 667f1f989f
commit 9944a594eb
2 changed files with 22 additions and 13 deletions

View file

@ -45,7 +45,6 @@ import org.keycloak.storage.SearchableModelField;
import java.util.Map;
import java.util.Objects;
import java.util.Spliterators;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@ -185,7 +184,7 @@ public class HotRodMapStorage<K, E extends AbstractHotRodEntity, V extends Abstr
public long delete(QueryParameters<M> queryParameters) {
IckleQueryMapModelCriteriaBuilder<E, M> iqmcb = queryParameters.getModelCriteriaBuilder()
.flashToModelCriteriaBuilder(createCriteriaBuilder());
String queryString = "SELECT id " + iqmcb.getIckleQuery();
String queryString = "DELETE " + iqmcb.getIckleQuery();
if (!queryParameters.getOrderBy().isEmpty()) {
queryString += " ORDER BY " + queryParameters.getOrderBy().stream().map(HotRodMapStorage::toOrderString)
@ -201,17 +200,7 @@ public class HotRodMapStorage<K, E extends AbstractHotRodEntity, V extends Abstr
query.setParameters(iqmcb.getParameters());
AtomicLong result = new AtomicLong();
CloseableIterator<Object[]> iterator = query.iterator();
StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, 0), false)
.peek(e -> result.incrementAndGet())
.map(a -> a[0])
.map(String.class::cast)
.forEach(this::delete);
iterator.close();
return result.get();
return query.executeStatement();
}
public IckleQueryMapModelCriteriaBuilder<E, M> createCriteriaBuilder() {

View file

@ -16,6 +16,7 @@
*/
package org.keycloak.testsuite.model;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.empty;
@ -34,6 +35,8 @@ import org.keycloak.models.RealmModel;
import org.keycloak.models.RealmProvider;
import org.keycloak.models.RoleModel;
import org.keycloak.models.RoleProvider;
import org.keycloak.models.map.client.MapClientProvider;
import org.keycloak.models.map.client.MapClientProviderFactory;
import java.util.LinkedList;
import java.util.List;
@ -149,6 +152,23 @@ public class ClientModelTest extends KeycloakModelTest {
}
}
@Test
@RequireProvider(value = ClientProvider.class, only = MapClientProviderFactory.PROVIDER_ID)
public void testDeleteClientUsingQueryParameters() {
final String CLIENT_ID = "createDeleteClientId";
// Create client
withRealm(realmId, (session, realm) -> session.clients().addClient(realm, CLIENT_ID));
// Check if exists
assertThat(withRealm(realmId, (session, realm) -> session.clients().getClientByClientId(realm, CLIENT_ID)), notNullValue());
// Remove
withRealm(realmId, (session, realm) -> {((MapClientProvider)session.clients()).preRemove(realm); return null;});
// Check is null
assertThat(withRealm(realmId, (session, realm) -> session.clients().getClientByClientId(realm, CLIENT_ID)), nullValue());
}
@Test
public void testScopeMappingRoleRemoval() {
// create two clients, one realm role and one client role and assign both to one of the clients