add using keyspace

This commit is contained in:
Albert Shift 2015-03-24 18:10:34 -07:00
parent 36b7ea9683
commit 5242b0ce75
8 changed files with 177 additions and 44 deletions

View file

@ -34,6 +34,8 @@ public abstract class AbstractSessionOperations {
abstract public Session currentSession();
abstract public String usingKeyspace();
abstract public boolean isShowCql();
abstract public Executor getExecutor();

View file

@ -36,6 +36,7 @@ import casser.core.tuple.Tuple6;
import casser.core.tuple.Tuple7;
import casser.mapping.CasserMappingEntity;
import casser.mapping.CasserMappingProperty;
import casser.mapping.CasserMappingRepository;
import casser.mapping.MappingUtil;
import com.datastax.driver.core.CloseFuture;
@ -44,20 +45,23 @@ import com.datastax.driver.core.Session;
public class CasserSession extends AbstractSessionOperations implements Closeable {
private final Session session;
private volatile String usingKeyspace;
private volatile boolean showCql;
private final Set<CasserMappingEntity<?>> dropEntitiesOnClose;
private final CasserEntityCache entityCache;
private final CasserMappingRepository mappingRepository;
private final Executor executor;
CasserSession(Session session,
String usingKeyspace,
boolean showCql,
Set<CasserMappingEntity<?>> dropEntitiesOnClose,
CasserEntityCache entityCache,
CasserMappingRepository mappingRepository,
Executor executor) {
this.session = session;
this.usingKeyspace = Objects.requireNonNull(usingKeyspace, "keyspace needs to be selected before creating session");
this.showCql = showCql;
this.dropEntitiesOnClose = dropEntitiesOnClose;
this.entityCache = entityCache;
this.mappingRepository = mappingRepository;
this.executor = executor;
}
@ -66,6 +70,11 @@ public class CasserSession extends AbstractSessionOperations implements Closeabl
return session;
}
@Override
public String usingKeyspace() {
return usingKeyspace;
}
@Override
public boolean isShowCql() {
return showCql;
@ -195,7 +204,7 @@ public class CasserSession extends AbstractSessionOperations implements Closeabl
Class<?> iface = MappingUtil.getMappingInterface(dsl);
CasserMappingEntity<?> entity = entityCache.getOrCreateEntity(iface);
CasserMappingEntity<?> entity = mappingRepository.getEntity(iface);
return new CountOperation(this, entity);
}
@ -214,7 +223,7 @@ public class CasserSession extends AbstractSessionOperations implements Closeabl
Class<?> iface = MappingUtil.getMappingInterface(pojo);
CasserMappingEntity<?> entity = entityCache.getOrCreateEntity(iface);
CasserMappingEntity<?> entity = mappingRepository.getEntity(iface);
return new UpsertOperation(this, entity, pojo);
}
@ -224,7 +233,7 @@ public class CasserSession extends AbstractSessionOperations implements Closeabl
Class<?> iface = MappingUtil.getMappingInterface(dsl);
CasserMappingEntity<?> entity = entityCache.getOrCreateEntity(iface);
CasserMappingEntity<?> entity = mappingRepository.getEntity(iface);
return new DeleteOperation(this, entity);
}

View file

@ -22,9 +22,12 @@ import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import casser.mapping.CasserMappingEntity;
import casser.mapping.CasserMappingRepository;
import casser.mapping.MappingUtil;
import casser.support.CasserException;
import casser.support.Requires;
import com.datastax.driver.core.KeyspaceMetadata;
import com.datastax.driver.core.Session;
import com.datastax.driver.core.TableMetadata;
import com.google.common.util.concurrent.MoreExecutors;
@ -33,16 +36,20 @@ import com.google.common.util.concurrent.MoreExecutors;
public class SessionInitializer extends AbstractSessionOperations {
private final Session session;
private String usingKeyspace;
private boolean showCql = false;
private Executor executor = MoreExecutors.sameThreadExecutor();
private Set<CasserMappingEntity<?>> dropEntitiesOnClose = null;
private CasserEntityCache entityCache = new CasserEntityCache();
private CasserMappingRepository mappingRepository = new CasserMappingRepository();
private boolean dropRemovedColumns = false;
private KeyspaceMetadata keyspaceMetadata;
SessionInitializer(Session session) {
this.session = Objects.requireNonNull(session, "empty session");
this.usingKeyspace = session.getLoggedKeyspace(); // can be null
}
@Override
@ -50,6 +57,11 @@ public class SessionInitializer extends AbstractSessionOperations {
return session;
}
@Override
public String usingKeyspace() {
return usingKeyspace;
}
@Override
public Executor getExecutor() {
return executor;
@ -87,40 +99,43 @@ public class SessionInitializer extends AbstractSessionOperations {
}
public SessionInitializer validate(Object... dsls) {
process(AutoDsl.VALIDATE, dsls);
initialize(AutoDsl.VALIDATE, dsls);
return this;
}
public SessionInitializer update(Object... dsls) {
process(AutoDsl.UPDATE, dsls);
initialize(AutoDsl.UPDATE, dsls);
return this;
}
public SessionInitializer create(Object... dsls) {
process(AutoDsl.CREATE, dsls);
initialize(AutoDsl.CREATE, dsls);
return this;
}
public SessionInitializer createDrop(Object... dsls) {
process(AutoDsl.CREATE_DROP, dsls);
initialize(AutoDsl.CREATE_DROP, dsls);
return this;
}
public SessionInitializer use(String keyspace) {
session.execute(SchemaUtil.useCql(keyspace, false));
this.usingKeyspace = keyspace;
return this;
}
public SessionInitializer use(String keyspace, boolean forceQuote) {
session.execute(SchemaUtil.useCql(keyspace, forceQuote));
this.usingKeyspace = keyspace;
return this;
}
public CasserSession get() {
return new CasserSession(session,
usingKeyspace,
showCql,
dropEntitiesOnClose,
entityCache,
mappingRepository,
executor);
}
@ -131,20 +146,22 @@ public class SessionInitializer extends AbstractSessionOperations {
CREATE_DROP;
}
private void process(AutoDsl type, Object[] dsls) {
private void initialize(AutoDsl type, Object[] dsls) {
for (Object dsl : dsls) {
processSingle(type, dsl);
Objects.requireNonNull(usingKeyspace, "please define keyspace by 'use' operator");
Requires.nonNullArray(dsls);
KeyspaceMetadata keyspaceMetadata = getKeyspaceMetadata();
mappingRepository.addEntities(dsls);
for (CasserMappingEntity<?> entity : mappingRepository.getKnownEntities()) {
initializeTable(type, entity);
}
}
private void processSingle(AutoDsl type, Object dsl) {
Objects.requireNonNull(dsl, "dsl is empty");
Class<?> iface = MappingUtil.getMappingInterface(dsl);
CasserMappingEntity<?> entity = entityCache.getOrCreateEntity(iface);
private void initializeTable(AutoDsl type, CasserMappingEntity<?> entity) {
if (type == AutoDsl.CREATE || type == AutoDsl.CREATE_DROP) {
createNewTable(entity);
@ -185,11 +202,16 @@ public class SessionInitializer extends AbstractSessionOperations {
return dropEntitiesOnClose;
}
private KeyspaceMetadata getKeyspaceMetadata() {
if (keyspaceMetadata == null) {
keyspaceMetadata = session.getCluster().getMetadata().getKeyspace(usingKeyspace.toLowerCase());
}
return keyspaceMetadata;
}
private TableMetadata getTableMetadata(CasserMappingEntity<?> entity) {
String tableName = entity.getTableName();
return session.getCluster().getMetadata().getKeyspace(session.getLoggedKeyspace().toLowerCase()).getTable(tableName.toLowerCase());
return getKeyspaceMetadata().getTable(tableName.toLowerCase());
}

View file

@ -0,0 +1,57 @@
/*
* 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 casser.mapping;
import java.util.Collection;
import java.util.Collections;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import casser.support.CasserMappingException;
public class CasserMappingRepository {
private ConcurrentMap<Class<?>, CasserMappingEntity<?>> entityMap = new ConcurrentHashMap<Class<?>, CasserMappingEntity<?>>();
private ConcurrentMap<String, CasserMappingUserType<?>> udtMap = new ConcurrentHashMap<String, CasserMappingUserType<?>>();
public void addEntities(Object[] dsls) {
for (Object dsl : dsls) {
Class<?> iface = MappingUtil.getMappingInterface(dsl);
entityMap.putIfAbsent(iface, new CasserMappingEntity(iface));
}
}
public Collection<CasserMappingEntity<?>> getKnownEntities() {
return Collections.unmodifiableCollection(entityMap.values());
}
public CasserMappingEntity<?> getEntity(Class<?> iface) {
CasserMappingEntity<?> entity = entityMap.get(iface);
if (entity == null) {
throw new CasserMappingException("please add all entities in SessionInitializer, unknown entity interface " + iface);
}
return entity;
}
}

View file

@ -0,0 +1,29 @@
/*
* 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 casser.mapping;
public class CasserMappingUserType<E> implements CasserUserType<E> {
public CasserMappingUserType(Class<E> clazz) {
}
@Override
public String getName() {
return null;
}
}

View file

@ -0,0 +1,22 @@
/*
* 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 casser.mapping;
public interface CasserUserType<E> {
public String getName();
}

View file

@ -13,31 +13,23 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package casser.core;
package casser.support;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.lang.reflect.Array;
import java.util.Objects;
import casser.mapping.CasserMappingEntity;
public class CasserEntityCache {
public final class Requires {
private ConcurrentMap<Class<?>, CasserMappingEntity<?>> cache = new ConcurrentHashMap<Class<?>, CasserMappingEntity<?>>();
private Requires() {
}
public CasserMappingEntity<?> getOrCreateEntity(Class<?> iface) {
CasserMappingEntity<?> entity = cache.get(iface);
if (entity == null) {
entity = new CasserMappingEntity(iface);
CasserMappingEntity<?> c = cache.putIfAbsent(iface, entity);
if (c != null) {
entity = c;
}
public static <T> void nonNullArray(T[] arr) {
Objects.requireNonNull(arr, "array is null");
int len = Array.getLength(arr);
for (int i = 0; i != len; ++i) {
Objects.requireNonNull(Array.get(arr, i), "element " + i + " is empty in array");
}
return entity;
}
}

View file

@ -21,8 +21,8 @@ import java.util.UUID;
import casser.mapping.ClusteringColumn;
import casser.mapping.Column;
import casser.mapping.PartitionKey;
import casser.mapping.DataTypeName;
import casser.mapping.PartitionKey;
import com.datastax.driver.core.DataType.Name;