make CasserMappingRepository immutable for multi-threading env
This commit is contained in:
parent
f5c990d18f
commit
e67bb3cd85
4 changed files with 117 additions and 80 deletions
|
@ -36,6 +36,7 @@ import com.noorq.casser.core.tuple.Tuple6;
|
|||
import com.noorq.casser.core.tuple.Tuple7;
|
||||
import com.noorq.casser.mapping.CasserMappingEntity;
|
||||
import com.noorq.casser.mapping.CasserMappingRepository;
|
||||
import com.noorq.casser.mapping.MappingRepositoryBuilder;
|
||||
import com.noorq.casser.mapping.MappingUtil;
|
||||
import com.noorq.casser.mapping.value.ColumnValuePreparer;
|
||||
import com.noorq.casser.mapping.value.ColumnValueProvider;
|
||||
|
@ -57,13 +58,13 @@ public class CasserSession extends AbstractSessionOperations implements Closeabl
|
|||
CasserSession(Session session,
|
||||
String usingKeyspace,
|
||||
boolean showCql,
|
||||
CasserMappingRepository mappingRepository,
|
||||
MappingRepositoryBuilder mappingRepositoryBuilder,
|
||||
Executor executor,
|
||||
boolean dropSchemaOnClose) {
|
||||
this.session = session;
|
||||
this.usingKeyspace = Objects.requireNonNull(usingKeyspace, "keyspace needs to be selected before creating session");
|
||||
this.showCql = showCql;
|
||||
this.mappingRepository = mappingRepository.setReadOnly();
|
||||
this.mappingRepository = mappingRepositoryBuilder.build();
|
||||
this.executor = executor;
|
||||
this.dropSchemaOnClose = dropSchemaOnClose;
|
||||
|
||||
|
|
|
@ -28,11 +28,10 @@ import com.datastax.driver.core.UserType;
|
|||
import com.google.common.util.concurrent.MoreExecutors;
|
||||
import com.noorq.casser.mapping.CasserEntityType;
|
||||
import com.noorq.casser.mapping.CasserMappingEntity;
|
||||
import com.noorq.casser.mapping.CasserMappingRepository;
|
||||
import com.noorq.casser.mapping.MappingRepositoryBuilder;
|
||||
import com.noorq.casser.mapping.value.ColumnValuePreparer;
|
||||
import com.noorq.casser.mapping.value.ColumnValueProvider;
|
||||
import com.noorq.casser.mapping.value.RowColumnValueProvider;
|
||||
import com.noorq.casser.mapping.value.StatementColumnValuePreparer;
|
||||
import com.noorq.casser.support.CasserException;
|
||||
|
||||
|
||||
public class SessionInitializer extends AbstractSessionOperations {
|
||||
|
@ -42,7 +41,7 @@ public class SessionInitializer extends AbstractSessionOperations {
|
|||
private boolean showCql = false;
|
||||
private Executor executor = MoreExecutors.sameThreadExecutor();
|
||||
|
||||
private CasserMappingRepository mappingRepository = new CasserMappingRepository();
|
||||
private MappingRepositoryBuilder mappingRepository = new MappingRepositoryBuilder();
|
||||
|
||||
private boolean dropUnusedColumns = false;
|
||||
private boolean dropUnusedIndexes = false;
|
||||
|
@ -74,12 +73,12 @@ public class SessionInitializer extends AbstractSessionOperations {
|
|||
|
||||
@Override
|
||||
public ColumnValueProvider getValueProvider() {
|
||||
return new RowColumnValueProvider(mappingRepository);
|
||||
throw new CasserException("not expected call");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ColumnValuePreparer getValuePreparer() {
|
||||
return new StatementColumnValuePreparer(mappingRepository);
|
||||
throw new CasserException("not expected call");
|
||||
}
|
||||
|
||||
public SessionInitializer showCql() {
|
||||
|
|
|
@ -16,92 +16,35 @@
|
|||
package com.noorq.casser.mapping;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.datastax.driver.core.DataType;
|
||||
import com.datastax.driver.core.UserType;
|
||||
import com.noorq.casser.support.CasserException;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.noorq.casser.support.CasserMappingException;
|
||||
import com.noorq.casser.support.Either;
|
||||
|
||||
public class CasserMappingRepository {
|
||||
|
||||
private final ImmutableMap<String, UserType> userTypeMap;
|
||||
|
||||
private static final Optional<CasserEntityType> OPTIONAL_UDT = Optional.of(CasserEntityType.USER_DEFINED_TYPE);
|
||||
|
||||
private final Map<Class<?>, CasserMappingEntity> entityMap = new HashMap<Class<?>, CasserMappingEntity>();
|
||||
private final ImmutableMap<Class<?>, CasserMappingEntity> entityMap;
|
||||
|
||||
private final Map<String, UserType> userTypeMap = new HashMap<String, UserType>();
|
||||
|
||||
private boolean readOnly = false;
|
||||
|
||||
public CasserMappingRepository setReadOnly() {
|
||||
this.readOnly = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void addUserType(String name, UserType userType) {
|
||||
|
||||
if (readOnly) {
|
||||
throw new CasserException("read-only mode");
|
||||
}
|
||||
|
||||
userTypeMap.putIfAbsent(name.toLowerCase(), userType);
|
||||
public CasserMappingRepository(MappingRepositoryBuilder builder) {
|
||||
|
||||
userTypeMap = ImmutableMap.<String, UserType>builder()
|
||||
.putAll(builder.getUserTypeMap())
|
||||
.build();
|
||||
|
||||
entityMap = ImmutableMap.<Class<?>, CasserMappingEntity>builder()
|
||||
.putAll(builder.getEntityMap())
|
||||
.build();
|
||||
|
||||
}
|
||||
|
||||
public UserType findUserType(String name) {
|
||||
return userTypeMap.get(name.toLowerCase());
|
||||
}
|
||||
|
||||
public void add(Object dsl) {
|
||||
add(dsl, Optional.empty());
|
||||
}
|
||||
|
||||
public void add(Object dsl, Optional<CasserEntityType> type) {
|
||||
|
||||
if (readOnly) {
|
||||
throw new CasserException("read-only mode");
|
||||
}
|
||||
|
||||
Class<?> iface = MappingUtil.getMappingInterface(dsl);
|
||||
|
||||
if (!entityMap.containsKey(iface)) {
|
||||
|
||||
CasserMappingEntity entity = type.isPresent() ?
|
||||
new CasserMappingEntity(iface, type.get()) :
|
||||
new CasserMappingEntity(iface);
|
||||
|
||||
if (null == entityMap.putIfAbsent(iface, entity)) {
|
||||
|
||||
addUserDefinedTypes(entity.getMappingProperties());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void addUserDefinedTypes(Collection<CasserMappingProperty> props) {
|
||||
|
||||
for (CasserMappingProperty prop : props) {
|
||||
|
||||
Either<DataType, IdentityName> type = prop.getColumnType();
|
||||
|
||||
if (type.isRight()) {
|
||||
|
||||
add(prop.getJavaType(), OPTIONAL_UDT);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Collection<CasserMappingEntity> entities() {
|
||||
return Collections.unmodifiableCollection(entityMap.values());
|
||||
return entityMap.values();
|
||||
}
|
||||
|
||||
public CasserMappingEntity getEntity(Class<?> iface) {
|
||||
|
@ -114,5 +57,4 @@ public class CasserMappingRepository {
|
|||
|
||||
return entity;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright (C) 2015 Noorq, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.noorq.casser.mapping;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.datastax.driver.core.DataType;
|
||||
import com.datastax.driver.core.UserType;
|
||||
import com.noorq.casser.support.Either;
|
||||
|
||||
public final class MappingRepositoryBuilder {
|
||||
|
||||
private static final Optional<CasserEntityType> OPTIONAL_UDT = Optional.of(CasserEntityType.USER_DEFINED_TYPE);
|
||||
|
||||
private final Map<Class<?>, CasserMappingEntity> entityMap = new HashMap<Class<?>, CasserMappingEntity>();
|
||||
|
||||
private final Map<String, UserType> userTypeMap = new HashMap<String, UserType>();
|
||||
|
||||
public CasserMappingRepository build() {
|
||||
return new CasserMappingRepository(this);
|
||||
}
|
||||
|
||||
public Collection<CasserMappingEntity> entities() {
|
||||
return entityMap.values();
|
||||
}
|
||||
|
||||
protected Map<Class<?>, CasserMappingEntity> getEntityMap() {
|
||||
return entityMap;
|
||||
}
|
||||
|
||||
protected Map<String, UserType> getUserTypeMap() {
|
||||
return userTypeMap;
|
||||
}
|
||||
|
||||
public void addUserType(String name, UserType userType) {
|
||||
userTypeMap.putIfAbsent(name.toLowerCase(), userType);
|
||||
}
|
||||
|
||||
public void add(Object dsl) {
|
||||
add(dsl, Optional.empty());
|
||||
}
|
||||
|
||||
public void add(Object dsl, Optional<CasserEntityType> type) {
|
||||
|
||||
Class<?> iface = MappingUtil.getMappingInterface(dsl);
|
||||
|
||||
if (!entityMap.containsKey(iface)) {
|
||||
|
||||
CasserMappingEntity entity = type.isPresent() ?
|
||||
new CasserMappingEntity(iface, type.get()) :
|
||||
new CasserMappingEntity(iface);
|
||||
|
||||
if (null == entityMap.putIfAbsent(iface, entity)) {
|
||||
|
||||
addUserDefinedTypes(entity.getMappingProperties());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void addUserDefinedTypes(Collection<CasserMappingProperty> props) {
|
||||
|
||||
for (CasserMappingProperty prop : props) {
|
||||
|
||||
Either<DataType, IdentityName> type = prop.getColumnType();
|
||||
|
||||
if (type.isRight()) {
|
||||
|
||||
add(prop.getJavaType(), OPTIONAL_UDT);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue