package com.tesora.dve.sql.schema; /* * #%L * Tesora Inc. * Database Virtualization Engine * %% * Copyright (C) 2011 - 2014 Tesora Inc. * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License, version 3, * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * #L% */ import java.util.List; import com.tesora.dve.common.catalog.CatalogEntity; import com.tesora.dve.common.catalog.ContainerTenant; import com.tesora.dve.common.catalog.ITenant; import com.tesora.dve.db.DBNative; import com.tesora.dve.db.Emitter; import com.tesora.dve.exceptions.PEException; import com.tesora.dve.server.global.HostService; import com.tesora.dve.singleton.Singletons; import com.tesora.dve.sql.SchemaException; import com.tesora.dve.sql.ParserException.Pass; import com.tesora.dve.sql.node.expression.LiteralExpression; import com.tesora.dve.sql.schema.cache.CacheSegment; import com.tesora.dve.sql.schema.cache.SchemaCacheKey; import com.tesora.dve.sql.schema.cache.SchemaEdge; import com.tesora.dve.sql.schema.mt.IPETenant; import com.tesora.dve.sql.util.Pair; public class PEContainerTenant extends Persistable<PEContainerTenant, ContainerTenant> implements IPETenant { private SchemaEdge<PEContainer> container; private String discriminant; @SuppressWarnings("unchecked") public PEContainerTenant(SchemaContext sc, PEContainer cont, String disc) { super(getContainerTenantKey(cont,disc)); setName(null); if (cont != null) container = StructuralUtils.buildEdge(sc,cont, false); if (container != null && disc == null) throw new SchemaException(Pass.SECOND, "Invalid discriminant"); discriminant = disc; setPersistent(sc,null,null); } public PEContainer getContainer(SchemaContext sc) { if (container == null) return null; return container.get(sc); } public SchemaCacheKey<PEContainer> getContainerCacheKey() { if (container == null) return null; return container.getCacheKey(); } public static PEContainerTenant load(ContainerTenant container, SchemaContext pc) { PEContainerTenant peContainer = (PEContainerTenant) pc.getLoaded(container,getContainerTenantKey(container)); if (peContainer == null) peContainer = new PEContainerTenant(pc, container); return peContainer; } @SuppressWarnings("unchecked") private PEContainerTenant(SchemaContext sc, ContainerTenant ct) { super(getContainerTenantKey(ct)); sc.startLoading(this, ct); setPersistent(sc, ct, ct.getId()); setName(null); if (ct.isGlobalTenant()) { discriminant = null; container = null; } else { discriminant = ct.getDiscriminant(); container = StructuralUtils.buildEdge(sc,PEContainer.load(ct.getContainer(),sc), true); } sc.finishedLoading(this, ct); } public String getDiscriminant() { return discriminant; } @Override public String getUniqueIdentifier() { return discriminant; } @Override public boolean isGlobalTenant() { return container == null && discriminant == null; } @Override public Long getTenantID() { if (getPersistentID() == null) return null; return new Long(getPersistentID()); } @Override protected Class<? extends CatalogEntity> getPersistentClass() { return ContainerTenant.class; } @Override protected int getID(ContainerTenant p) { return p.getId(); } @Override protected ContainerTenant lookup(SchemaContext sc) throws PEException { return null; } @Override protected ContainerTenant createEmptyNew(SchemaContext sc) throws PEException { if (discriminant == null) return null; return new ContainerTenant(container.get(sc).getPersistent(sc),discriminant); } @Override protected void populateNew(SchemaContext sc, ContainerTenant p) throws PEException { } @Override protected Persistable<PEContainerTenant, ContainerTenant> load( SchemaContext sc, ContainerTenant p) throws PEException { return null; } @Override public ContainerTenant getPersistent(SchemaContext pc, boolean create) { if (discriminant == null) return ContainerTenant.GLOBAL_CONTAINER_TENANT; return super.getPersistent(pc,create); } @Override public ITenant getPersistentTenant(SchemaContext sc) throws PEException { return getPersistent(sc); } @Override protected String getDiffTag() { return null; } public static String buildDiscriminantValue(SchemaContext sc, ConnectionValues cv, List<Pair<PEColumn,LiteralExpression>> orderedValues) { StringBuilder buf = new StringBuilder(); Emitter emitter = Singletons.require(DBNative.class).getEmitter(); for(Pair<PEColumn,LiteralExpression> p : orderedValues) { if (buf.length() > 0) buf.append(","); LiteralExpression litex = p.getSecond(); buf.append(p.getFirst().getName().get()).append(":"); emitter.emitLiteral(cv, litex, buf); } return buf.toString(); } private static final ContainerTenantCacheKey globalContainerTenantCacheKey = new ContainerTenantCacheKey("GLOBAL","UNUSED"); public static SchemaCacheKey<PEContainerTenant> getContainerTenantKey(ContainerTenant ct) { if (ct.isGlobalTenant()) return globalContainerTenantCacheKey; return new ContainerTenantCacheKey(ct.getContainer().getName(), ct.getDiscriminant()); } public static SchemaCacheKey<PEContainerTenant> getContainerTenantKey(PEContainer cont, String disc) { if (cont == null && disc == null) return globalContainerTenantCacheKey; return new ContainerTenantCacheKey(cont.getName().getUnquotedName().get(),disc); } public static class ContainerTenantCacheKey extends SchemaCacheKey<PEContainerTenant> { /** * */ private static final long serialVersionUID = 1L; private String containerName; private String discriminant; public ContainerTenantCacheKey(String ofContainer, String keyvals) { super(); containerName = ofContainer; discriminant = keyvals; } @Override public int hashCode() { return addHash(initHash(PEContainerTenant.class,containerName.hashCode()),discriminant.hashCode()); } @Override public String toString() { return "PEContainerTenant:" + containerName + "(" + discriminant + ")"; } @Override public boolean equals(Object o) { if (o instanceof ContainerTenantCacheKey) { ContainerTenantCacheKey octk = (ContainerTenantCacheKey) o; return octk.containerName.equals(containerName) && octk.discriminant.equals(discriminant); } return false; } @Override public PEContainerTenant load(SchemaContext sc) { ContainerTenant ten = null; if (isGlobalTenant()) ten = ContainerTenant.GLOBAL_CONTAINER_TENANT; else ten = sc.getCatalog().findContainerTenant(containerName, discriminant); if (ten == null) return null; return PEContainerTenant.load(ten, sc); } @Override public CacheSegment getCacheSegment() { return CacheSegment.TENANT; } public boolean isGlobalTenant() { return "GLOBAL".equals(containerName) && "UNUSED".equals(discriminant); } } }