/* * Copyright (c) 2009-2012, 2015 Eike Stepper (Berlin, Germany) and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Kai Schlamp - initial API and implementation * Eike Stepper - maintenance * Stefan Winkler - Bug 285426: [DB] Implement user-defined typeMapping support */ package org.eclipse.emf.cdo.tests.db; import org.eclipse.emf.cdo.eresource.CDOResource; import org.eclipse.emf.cdo.session.CDOSession; import org.eclipse.emf.cdo.tests.AbstractCDOTest; import org.eclipse.emf.cdo.tests.config.impl.ConfigTest.Skips; import org.eclipse.emf.cdo.tests.db.verifier.DBStoreVerifier; import org.eclipse.emf.cdo.tests.model1.Model1Package; import org.eclipse.emf.cdo.transaction.CDOTransaction; import org.eclipse.emf.cdo.util.CommitException; import org.eclipse.net4j.db.DBUtil; import org.eclipse.emf.ecore.EAnnotation; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EPackage; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecore.EcoreFactory; import org.eclipse.emf.ecore.util.EcoreUtil; import java.sql.ResultSet; /** * Test different DB annotations. * * @author Kai Schlamp */ // XXX PSQL fails, too - need to investigate @Skips("Postgresql") public class DBAnnotationsTest extends AbstractCDOTest { private static int modelCounter; public void testLengthAnnotationPositive() throws Exception { msg("Opening session"); EPackage model1 = createModel(); addLengthAnnotation(model1, "8"); CDOSession session = openSession(); session.getPackageRegistry().putEPackage(model1); msg("Opening transaction"); CDOTransaction transaction = session.openTransaction(); msg("Creating resource"); CDOResource resource = transaction.createResource(getResourcePath("/test1")); msg("Commit a product that has a name with an allowed string length."); EClass eClass = (EClass)model1.getEClassifier("Product1"); EObject product = model1.getEFactoryInstance().create(eClass); product.eSet(eClass.getEStructuralFeature("name"), "01234567"); resource.getContents().add(product); transaction.commit(); transaction.close(); session.close(); } // HSQL does not support length annotations @Skips("Hsqldb") public void testLengthAnnotationNegative() throws Exception { msg("Opening session"); EPackage model1 = createModel(); addLengthAnnotation(model1, "8"); CDOSession session = openSession(); session.getPackageRegistry().putEPackage(model1); msg("Opening transaction"); CDOTransaction transaction = session.openTransaction(); msg("Creating resource"); CDOResource resource = transaction.createResource(getResourcePath("/test1")); msg("Commit a product that has a name with an invalid string length."); EClass eClass = (EClass)model1.getEClassifier("Product1"); EObject product = model1.getEFactoryInstance().create(eClass); product.eSet(eClass.getEStructuralFeature("name"), "012345678"); resource.getContents().add(product); try { transaction.commit(); fail("Committing too long data did not result in an exception"); } catch (Exception success) { } finally { transaction.close(); session.close(); } } public void testLengthAnnotationByMetaData() throws CommitException { msg("Opening session"); final EPackage model1 = createModel(); addLengthAnnotation(model1, "8"); CDOSession session = openSession(); session.getPackageRegistry().putEPackage(model1); msg("Opening transaction"); CDOTransaction transaction = session.openTransaction(); msg("Creating resource"); CDOResource resource = transaction.createResource(getResourcePath("/test1")); msg("Commit a product."); EClass eClass = (EClass)model1.getEClassifier("Product1"); EObject product = model1.getEFactoryInstance().create(eClass); resource.getContents().add(product); transaction.commit(); transaction.close(); session.close(); msg("Check if column size was correctly set."); new DBStoreVerifier(getRepository()) { @Override protected void doVerify() throws Exception { String tableName = model1.getName().toUpperCase() + "_PRODUCT1"; ResultSet rset = getMetaData().getColumns(null, null, tableName, "NAME"); try { rset.next(); assertEquals("8", rset.getString(7)); } finally { DBUtil.close(rset); } } }.verify(); } // HSQL does not support type annotations @Skips("Hsqldb") public void testTypeAnnotationByMetaData() throws CommitException { msg("Opening session"); final EPackage model1 = createModel(); addTypeAnnotation(model1, "CLOB"); CDOSession session = openSession(); session.getPackageRegistry().putEPackage(model1); msg("Opening transaction"); CDOTransaction transaction = session.openTransaction(); msg("Creating resource"); CDOResource resource = transaction.createResource(getResourcePath("/test1")); msg("Commit a category."); EClass eClass = (EClass)model1.getEClassifier("Category"); EObject category = model1.getEFactoryInstance().create(eClass); resource.getContents().add(category); transaction.commit(); transaction.close(); session.close(); msg("Check if column type was correctly set."); new DBStoreVerifier(getRepository()) { @Override protected void doVerify() throws Exception { String tableName = model1.getName().toUpperCase() + "_CATEGORY"; ResultSet rset = getMetaData().getColumns(null, null, tableName, "NAME"); try { rset.next(); assertEquals("CLOB", rset.getString(6)); } finally { DBUtil.close(rset); } } }.verify(); } public void testTableNameAnnotationByMetaData() throws CommitException { msg("Opening session"); EPackage model1 = createModel(); addTableNameAnnotation(model1, "Subject"); CDOSession session = openSession(); session.getPackageRegistry().putEPackage(model1); msg("Opening transaction"); CDOTransaction transaction = session.openTransaction(); msg("Creating resource"); CDOResource resource = transaction.createResource(getResourcePath("/test1")); msg("Commit a category."); EClass eClass = (EClass)model1.getEClassifier("Category"); EObject category = model1.getEFactoryInstance().create(eClass); resource.getContents().add(category); transaction.commit(); transaction.close(); session.close(); msg("Check if table name was correctly set."); new DBStoreVerifier(getRepository()) { @Override protected void doVerify() throws Exception { ResultSet rset = getMetaData().getTables(null, null, "SUBJECT", null); try { rset.next(); assertEquals("SUBJECT", rset.getString(3)); } finally { DBUtil.close(rset); } } }.verify(); } public void testColumnNameAnnotationByMetaData() throws CommitException { msg("Opening session"); final EPackage model1 = createModel(); addColumnNameAnnotation(model1, "TOPIC"); CDOSession session = openSession(); session.getPackageRegistry().putEPackage(model1); msg("Opening transaction"); CDOTransaction transaction = session.openTransaction(); msg("Creating resource"); CDOResource resource = transaction.createResource(getResourcePath("/test1")); msg("Commit a category."); EClass eClass = (EClass)model1.getEClassifier("Category"); EObject category = model1.getEFactoryInstance().create(eClass); resource.getContents().add(category); transaction.commit(); transaction.close(); session.close(); msg("Check if table name was correctly set."); new DBStoreVerifier(getRepository()) { @Override protected void doVerify() throws Exception { String tableName = model1.getName().toUpperCase() + "_CATEGORY"; ResultSet rset = getMetaData().getColumns(null, null, tableName, "TOPIC"); try { rset.next(); assertEquals("TOPIC", rset.getString(4)); } finally { DBUtil.close(rset); } } }.verify(); } // HSQL does not support type annotations @Skips("Hsqldb") public void testColumnNameTypeAnnotationByMetaData() throws CommitException { msg("Opening session"); final EPackage model1 = createModel(); addColumnNameAndTypeAnnoation(model1, "TOPIC", "CLOB"); CDOSession session = openSession(); session.getPackageRegistry().putEPackage(model1); msg("Opening transaction"); CDOTransaction transaction = session.openTransaction(); msg("Creating resource"); CDOResource resource = transaction.createResource(getResourcePath("/test1")); msg("Commit a category."); EClass eClass = (EClass)model1.getEClassifier("Category"); EObject category = model1.getEFactoryInstance().create(eClass); resource.getContents().add(category); transaction.commit(); transaction.close(); session.close(); msg("Check if table name was correctly set."); new DBStoreVerifier(getRepository()) { @Override protected void doVerify() throws Exception { String tableName = model1.getName().toUpperCase() + "_CATEGORY"; ResultSet rset = getMetaData().getColumns(null, null, tableName, "TOPIC"); try { rset.next(); assertEquals("TOPIC", rset.getString(4)); assertEquals("CLOB", rset.getString(6)); } finally { DBUtil.close(rset); } } }.verify(); } public void testTableMappingAnnotationByMetaData() throws CommitException { msg("Opening session"); final EPackage model1 = createModel(); addTableMappingAnnotation(model1, "OrderDetail", "Company"); CDOSession session = openSession(); session.getPackageRegistry().putEPackage(model1); msg("Opening transaction"); CDOTransaction transaction = session.openTransaction(); msg("Creating resource"); CDOResource resource = transaction.createResource(getResourcePath("/test1")); msg("Commit a category."); EClass eClass = (EClass)model1.getEClassifier("Category"); EObject category = model1.getEFactoryInstance().create(eClass); resource.getContents().add(category); transaction.commit(); transaction.close(); session.close(); msg("Check if table name was correctly set."); new DBStoreVerifier(getRepository()) { @Override protected void doVerify() throws Exception { ResultSet rset = getMetaData().getTables(null, null, null, null); try { boolean orderDetailTableCreated = false; boolean companyTableCreated = false; boolean categoryTableCreated = false; String prefix = model1.getName().toUpperCase() + '_'; while (rset.next()) { String tableName = rset.getString(3); if ((prefix + "ORDERDETAIL").equalsIgnoreCase(tableName)) { orderDetailTableCreated = true; } else if ((prefix + "COMPANY").equalsIgnoreCase(tableName)) { companyTableCreated = true; } else if ((prefix + "CATEGORY").equalsIgnoreCase(tableName)) { categoryTableCreated = true; } } assertEquals(false, orderDetailTableCreated); assertEquals(false, companyTableCreated); assertEquals(true, categoryTableCreated); } finally { DBUtil.close(rset); } } }.verify(); } private EPackage createModel() { EPackage ePackage = EcoreUtil.copy(getModel1Package()); String suffix = "_dynamic" + modelCounter++; ePackage.setNsURI(ePackage.getNsURI() + suffix); ePackage.setName(ePackage.getName() + suffix); return ePackage; } private void addLengthAnnotation(EPackage model1, String value) { EAnnotation annotation = EcoreFactory.eINSTANCE.createEAnnotation(); annotation.setSource("http://www.eclipse.org/CDO/DBStore"); annotation.getDetails().put("columnLength", value); EClass product1 = (EClass)model1.getEClassifier("Product1"); EStructuralFeature element = product1.getEStructuralFeature(Model1Package.PRODUCT1__NAME); element.getEAnnotations().add(annotation); } private void addTypeAnnotation(EPackage model1, String value) { EAnnotation annotation = EcoreFactory.eINSTANCE.createEAnnotation(); annotation.setSource("http://www.eclipse.org/CDO/DBStore"); annotation.getDetails().put("columnType", value); EClass category = (EClass)model1.getEClassifier("Category"); EStructuralFeature element = category.getEStructuralFeature(Model1Package.CATEGORY__NAME); element.getEAnnotations().add(annotation); } private void addTableNameAnnotation(EPackage model1, String value) { EAnnotation annotation = EcoreFactory.eINSTANCE.createEAnnotation(); annotation.setSource("http://www.eclipse.org/CDO/DBStore"); annotation.getDetails().put("tableName", value); EClass category = (EClass)model1.getEClassifier("Category"); category.getEAnnotations().add(annotation); } private void addColumnNameAnnotation(EPackage model1, String value) { EAnnotation annotation = EcoreFactory.eINSTANCE.createEAnnotation(); annotation.setSource("http://www.eclipse.org/CDO/DBStore"); annotation.getDetails().put("columnName", value); EClass category = (EClass)model1.getEClassifier("Category"); EStructuralFeature element = category.getEStructuralFeature(Model1Package.CATEGORY__NAME); element.getEAnnotations().add(annotation); } private void addColumnNameAndTypeAnnoation(EPackage model1, String name, String type) { EAnnotation annotation = EcoreFactory.eINSTANCE.createEAnnotation(); annotation.setSource("http://www.eclipse.org/CDO/DBStore"); annotation.getDetails().put("columnName", name); annotation.getDetails().put("columnType", type); EClass category = (EClass)model1.getEClassifier("Category"); EStructuralFeature element = category.getEStructuralFeature(Model1Package.CATEGORY__NAME); element.getEAnnotations().add(annotation); } private void addTableMappingAnnotation(EPackage model1, String... unmappedTables) { for (String unmappedTable : unmappedTables) { EAnnotation annotation = EcoreFactory.eINSTANCE.createEAnnotation(); annotation.setSource("http://www.eclipse.org/CDO/DBStore"); annotation.getDetails().put("tableMapping", "NONE"); // ID is defined in plugin.xml annotation.getDetails().put("typeMapping", "org.eclipse.emf.cdo.tests.db.EIntToVarchar"); EClass orderDetail = (EClass)model1.getEClassifier(unmappedTable); orderDetail.getEAnnotations().add(annotation); } } }