Java tutorial
/* * Copyright 2011-2017 B2i Healthcare Pte Ltd, http://b2i.sg * * 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.b2international.snowowl.datastore.server; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Arrays; import java.util.Set; import org.eclipse.emf.cdo.common.id.CDOIDUtil; import org.eclipse.emf.cdo.common.model.CDOModelUtil; import org.eclipse.emf.cdo.server.IRepository; import org.eclipse.emf.cdo.server.ISession; import org.eclipse.emf.cdo.server.StoreThreadLocal; import org.eclipse.emf.cdo.server.db.IDBStore; import org.eclipse.emf.cdo.server.db.IDBStoreAccessor; import org.eclipse.emf.cdo.server.db.mapping.IClassMapping; import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageRegistry; import org.eclipse.emf.cdo.spi.server.InternalRepository; import org.eclipse.emf.cdo.spi.server.InternalSession; import org.eclipse.emf.cdo.spi.server.InternalStore; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EClassifier; import org.eclipse.emf.ecore.EPackage; import org.eclipse.net4j.db.DBUtil; import org.eclipse.net4j.db.ddl.IDBField; import org.eclipse.net4j.db.ddl.IDBTable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.b2international.commons.collections.Collections3; import com.b2international.commons.collections.Procedure; import com.b2international.commons.db.JdbcUrl; import com.b2international.commons.db.JdbcUtils; import com.b2international.snowowl.core.ApplicationContext; import com.b2international.snowowl.core.api.SnowowlRuntimeException; import com.b2international.snowowl.datastore.cdo.ICDORepository; import com.b2international.snowowl.datastore.cdo.ICDORepositoryManager; import com.b2international.snowowl.datastore.config.RepositoryConfiguration; import com.google.common.base.Function; import com.google.common.base.Preconditions; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Sets; /** * Server side utility class for the object-relational backend. */ public class ServerDbUtils { private static final Logger LOGGER = LoggerFactory.getLogger(CDOServerUtils.class); /** * The unique name of the index for the CDO_CREATED column. * <br>Name: {@value}. */ private static final String CDO_CREATED_IDX = "CDO_CREATED_IDX"; public static long getClassMetaID(final EClass eClass) { final ICDORepositoryManager repositoryManager = ApplicationContext.getInstance() .getService(ICDORepositoryManager.class); final ICDORepository cdoRepository = repositoryManager.get(eClass); final IDBStore dbStore = cdoRepository.getDbStore(); final IRepository repository = cdoRepository.getRepository(); final ISession session = repository.getSessionManager().getSessions()[0]; StoreThreadLocal.setSession((InternalSession) session); final long lastCommitTime = dbStore.getLastCommitTime(); return CDOIDUtil.getLong(dbStore.getMetaDataManager().getMetaID(eClass, lastCommitTime)); } /** * Creates an index for the CDO_CREATED DB column for all tables mapped to the specified package. * <br>This method, first, tried to drop the existing CDO_CREATED index, if any. * @param nsUri the unique namespace URI for the package containing all classifiers that are mapped to an ORM backend. * @param otherNsUris additional packages. */ public static void createCdoCreatedIndexOnTables(final ICDORepository repository) { Preconditions.checkNotNull(repository, "Repository argument cannot be null."); final InternalRepository internalRepository = (InternalRepository) repository.getRepository(); final InternalStore store = internalRepository.getStore(); if (store instanceof IDBStore) { try { final IDBStore dbStore = (IDBStore) store; final IDBStoreAccessor accessor = dbStore.getWriter(null); //set accessor on thread local StoreThreadLocal.setAccessor(accessor); final InternalCDOPackageRegistry packageRegistry = internalRepository.getPackageRegistry(); final Set<String> nsUris = Sets .newHashSet(Iterables.transform(Arrays.asList(((CDORepository) repository).getEPackages()), new Function<EPackage, String>() { @Override public String apply(final EPackage ePackage) { return Preconditions.checkNotNull(ePackage).getNsURI(); } })); //process namespace URIs for (final String _nsUri : nsUris) { final EPackage _package = packageRegistry.getEPackage(_nsUri); if (null == _package) { LOGGER.warn("Cannot found package in registry for '" + _nsUri + "'."); continue; } else { for (final EClassifier classifier : _package.getEClassifiers()) { if (classifier instanceof EClass) { final EClass eclass = (EClass) classifier; if (eclass.isAbstract()) { continue; //abstract classes are not mapped } if (eclass.isInterface()) { continue; //interfaces are not mapped } if (CDOModelUtil.isCorePackage(_package)) { continue; //do not create indexes and class mapping for ecore packages } final IClassMapping classMapping = dbStore.getMappingStrategy() .getClassMapping(eclass); for (final IDBTable table : classMapping.getDBTables()) { @SuppressWarnings("restriction") final IDBField createdField = table.getField( org.eclipse.emf.cdo.server.internal.db.CDODBSchema.ATTRIBUTES_CREATED); if (null != createdField) { Connection connection = null; PreparedStatement createStatement = null; PreparedStatement dropStatement = null; final String tableName = table.getName().toUpperCase(); final String indexName = tableName + "_" + CDO_CREATED_IDX; final String createdFieldName = createdField.getName().toUpperCase(); try { connection = repository.getConnection(); boolean indexExists = false; try (ResultSet info = connection.getMetaData().getIndexInfo( connection.getCatalog(), null, tableName, false, false)) { while (info.next()) { if (indexName.equals(info.getString("INDEX_NAME"))) { indexExists = true; break; } } } if (!indexExists) { LOGGER.info("Creating index '" + indexName + "' on table '" + tableName + "'."); final String createIndexSql = "CREATE INDEX " + indexName + " ON " + tableName + "(" + createdFieldName + ")"; JdbcUtils.executeUpdate(connection, createIndexSql); } } catch (final SQLException e) { LOGGER.error("Cannot create index for " + tableName); throw new SnowowlRuntimeException(e); } finally { DBUtil.close(connection); DBUtil.close(dropStatement); DBUtil.close(createStatement); } } } } } } } } finally { StoreThreadLocal.release(); } } else { LOGGER.warn("CDO store is not backed by a object/relational mapper."); } return; } /** * Creates an index for the CDO_CREATED DB column for all tables mapped to the specified package. * <br>This method, first, tried to drop the existing CDO_CREATED index, if any. * @param nsUri the unique namespace URI for the package containing all classifiers that are mapped to an ORM backend. * @param otherNsUris additional packages. */ public static void createCdoCreatedIndexOnTables(final String nsUri, final String... otherNsUris) { Preconditions.checkNotNull(nsUri, "Namespace URI argument cannot be null."); final Set<ICDORepository> repositories = Sets.newHashSet( Iterables.transform(Lists.asList(nsUri, otherNsUris), new Function<String, ICDORepository>() { @Override public ICDORepository apply(final String _nsUri) { return getRepository(_nsUri); } })); Collections3.forEach(repositories, new Procedure<ICDORepository>() { @Override protected void doApply(final ICDORepository repository) { createCdoCreatedIndexOnTables(repository); } }); } public static Connection createConnection(final EPackage ePackage, final RepositoryConfiguration configuration) { Preconditions.checkNotNull(ePackage, "EClass argument cannot be null."); final String driverName = configuration.getDatabaseConfiguration().getDriverClass(); final JdbcUrl jdbcUrl = configuration.getDatabaseUrl(); final String username = configuration.getDatabaseConfiguration().getUsername(); final String password = configuration.getDatabaseConfiguration().getPassword(); final ICDORepositoryManager repositoryManager = ApplicationContext.getInstance() .getService(ICDORepositoryManager.class); final String repositoryUuid = repositoryManager.get(ePackage).getUuid(); final String localDbUrl = jdbcUrl.build(repositoryUuid); return JdbcUtils.createConnection(driverName, localDbUrl, username, password); } /*returns with the repository instance*/ private static ICDORepository getRepository(final String nsUri) { Preconditions.checkNotNull(nsUri, "Namespace URI argument cannot be null."); final ICDORepositoryManager repositoryManager = ApplicationContext.getInstance() .getService(ICDORepositoryManager.class); return repositoryManager.get(nsUri); } }