Author: tchemit Date: 2011-11-12 20:21:01 +0100 (Sat, 12 Nov 2011) New Revision: 2378 Url: http://nuiton.org/repositories/revision/topia/2378 Log: Evolution #1801: Open TopiaSQLQuery api Evolution #1802: Add methods to avoid expose hibernate api Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaContextImpl.java trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaSQLQuery.java trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaUtil.java trunk/topia-persistence/src/test/java/org/nuiton/topia/framework/TopiaUtilTest.java Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaContextImpl.java =================================================================== --- trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaContextImpl.java 2011-10-28 21:25:50 UTC (rev 2377) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaContextImpl.java 2011-11-12 19:21:01 UTC (rev 2378) @@ -1405,8 +1405,7 @@ checkClosed(_( "topia.persistence.error.unsupported.operation.on.closed.context", "replicateEntity")); - boolean result = TopiaUtil.isSchemaExist(hibernateConfiguration, - clazz.getName()); + boolean result = TopiaUtil.isSchemaExist(this, clazz.getName()); return result; } Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaSQLQuery.java =================================================================== --- trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaSQLQuery.java 2011-10-28 21:25:50 UTC (rev 2377) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaSQLQuery.java 2011-11-12 19:21:01 UTC (rev 2378) @@ -31,9 +31,12 @@ import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; +import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; /** * An executor of sql query which permits to obtain a single result via @@ -83,12 +86,8 @@ try { ResultSet set = ps.executeQuery(); - if (set.next()) { - O singleResult = prepareResult(set); - if (singleResult != null) { - result.add(singleResult); - } - } + findSingleResult(result, set); + } catch (Exception e) { throw new TopiaRuntimeException("Could not execute query", e); } finally { @@ -118,13 +117,8 @@ try { ResultSet set = ps.executeQuery(); - while (set.next()) { - O singleResult = prepareResult(set); + findMultipleResult(result, set); - if (singleResult != null) { - result.add(singleResult); - } - } } catch (Exception e) { throw new TopiaRuntimeException("Could not execute query", e); } finally { @@ -135,4 +129,121 @@ return result; } + /** + * A hook to obtain the result set just after the query execute. + * + * @param set the result set just obtained + * @throws SQLException if any prob + * @since 2.6.4 + */ + protected void afterExecuteQuery(ResultSet set) throws SQLException { + // by default do nothing + } + + /** + * Obtain a single result given the result set and push in in the result list. + * + * @param result the result list + * @param set the set of the executed sql query + * @throws SQLException if any pb + * @since 2.6.4 + */ + protected void findSingleResult(List<O> result, + ResultSet set) throws SQLException { + + afterExecuteQuery(set); + + if (set.next()) { + O singleResult = prepareResult(set); + if (singleResult != null) { + result.add(singleResult); + } + } + } + + /** + * Obtain a multi result given the result set and push in in the result list. + * + * @param result the result list + * @param set the set of the executed sql query + * @throws SQLException if any pb + * @since 2.6.4 + */ + protected void findMultipleResult(List<O> result, + ResultSet set) throws SQLException { + + afterExecuteQuery(set); + + while (set.next()) { + O singleResult = prepareResult(set); + + if (singleResult != null) { + result.add(singleResult); + } + } + } + + /** + * Obtain the column names of a given result set using his metadata. + * + * @param set the result set to inspect + * @return the column names of the result set + * @throws SQLException if any pb + * @since 2.6.4 + */ + protected String[] getColumnNames(ResultSet set) throws SQLException { + ResultSetMetaData metaData = set.getMetaData(); + int columnCount = metaData.getColumnCount(); + String[] result = new String[columnCount]; + for (int i = 0; i < columnCount; i++) { + result[i] = metaData.getColumnName(i + 1); + } + return result; + } + + /** + * From a given result set, let's count his number of row. + * <p/> + * <strong>Note:</strong> the result set must be scrollable to go back to + * before first row. + * + * @param set the result set to inspect + * @return the number of row of the given result set + * @throws SQLException if any pb + * @since 2.6.4 + */ + protected int getNbRows(ResultSet set) throws SQLException { + + int nbRows = 0; + while (set.next()) { + nbRows++; + } + // go back before first row (be ware the resultset must be scrollable) + set.beforeFirst(); + return nbRows; + } + + /** + * Given the column names of the result set, transform the row of the + * result set to a map with column name as key. + * + * @param columnNames column names of the result set + * @param set the set to inspect + * @return the map for the given row of the result set + * @throws SQLException if any pb + * @since 2.6.4 + */ + protected Map<String, Object> getRowAsMap(String[] columnNames, + ResultSet set) throws SQLException { + + Map<String, Object> result = new LinkedHashMap<String, Object>(); + int length = columnNames.length; + for (int i = 0; i < length; i++) { + String name = columnNames[i]; + Object value = set.getObject(i + 1); + result.put(name, value); + } + return result; + } + } Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaUtil.java =================================================================== --- trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaUtil.java 2011-10-28 21:25:50 UTC (rev 2377) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaUtil.java 2011-11-12 19:21:01 UTC (rev 2378) @@ -34,6 +34,7 @@ import org.hibernate.mapping.Table; import org.hibernate.tool.hbm2ddl.DatabaseMetadata; import org.hibernate.tool.hbm2ddl.TableMetadata; +import org.nuiton.topia.TopiaContext; import org.nuiton.topia.TopiaContextFactory; import org.nuiton.topia.TopiaNotFoundException; import org.nuiton.topia.persistence.TopiaEntity; @@ -163,6 +164,76 @@ * Test si une entite donnee correspondant a une configuration existe en * base. * + * @param tx la session topia + * @param entityName le nom de l'entite a tester + * @return <tt>true</tt> si le schema de la table existe + * @since 2.6.4 + */ + public static boolean isSchemaExist(TopiaContext tx, + String entityName) { + + boolean exist = false; + + try { + Configuration configuration = + ((TopiaContextImplementor) tx).getHibernateConfiguration(); + PersistentClass classMapping = + configuration.getClassMapping(entityName); + if (classMapping == null) { + if (log.isInfoEnabled()) { + Iterator<?> itr = configuration.getClassMappings(); + while (itr.hasNext()) { + log.info("available mapping " + itr.next()); + } + } + throw new IllegalArgumentException( + "could not find entity with name " + entityName); + } + Table testTable = classMapping.getTable(); + + if (testTable == null) { + throw new IllegalArgumentException( + "could not find entity with name " + entityName); + } + ConnectionProvider connectionProvider = + ConnectionProviderFactory.newConnectionProvider( + configuration.getProperties()); + + Dialect dialect = Dialect.getDialect(configuration.getProperties()); + + Connection connection = null; + try { + connection = connectionProvider.getConnection(); + + DatabaseMetadata meta = new DatabaseMetadata(connection, dialect); + + TableMetadata tmd = meta.getTableMetadata( + testTable.getName(), testTable.getSchema(), + testTable.getCatalog(), testTable.isQuoted()); + + if (tmd != null) { + //table exist + exist = true; + } + } finally { + if (connection != null) { + connection.close(); + } + } + + } catch (SQLException e) { + log.error("Cant connect to database", e); + } catch (TopiaNotFoundException e) { + log.error("Cant connect to database", e); + } + + return exist; + } + + /** + * Test si une entite donnee correspondant a une configuration existe en + * base. + * * @param configuration la configuration hibernate * @param entityName le nom de l'entite a tester * @return <tt>true</tt> si le schema de la table existe Modified: trunk/topia-persistence/src/test/java/org/nuiton/topia/framework/TopiaUtilTest.java =================================================================== --- trunk/topia-persistence/src/test/java/org/nuiton/topia/framework/TopiaUtilTest.java 2011-10-28 21:25:50 UTC (rev 2377) +++ trunk/topia-persistence/src/test/java/org/nuiton/topia/framework/TopiaUtilTest.java 2011-11-12 19:21:01 UTC (rev 2378) @@ -25,9 +25,6 @@ package org.nuiton.topia.framework; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.hibernate.cfg.Configuration; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; @@ -61,8 +58,6 @@ private static TopiaContext rootContext; - private static final Log log = LogFactory.getLog(TopiaUtilTest.class); - @BeforeClass public static void setUpClass() throws Exception { @@ -114,21 +109,20 @@ @Test(expected = IllegalArgumentException.class) public void testIsSchemaExistFailed() throws Exception { - Configuration conf = ((TopiaContextImplementor) rootContext).getHibernateConfiguration(); - TopiaUtil.isSchemaExist(conf, "fake"); + TopiaUtil.isSchemaExist(rootContext, "fake"); } @Test public void testIsSchemaExist() throws Exception { - Configuration conf = ((TopiaContextImplementor) rootContext).getHibernateConfiguration(); - boolean actual = TopiaUtil.isSchemaExist(conf, PersonImpl.class.getName()); + boolean actual = TopiaUtil.isSchemaExist(rootContext, + PersonImpl.class.getName()); assertFalse(actual); TopiaContext tx = rootContext.beginTransaction(); try { tx.createSchema(); - actual = TopiaUtil.isSchemaExist(conf, PersonImpl.class.getName()); + actual = TopiaUtil.isSchemaExist(rootContext, PersonImpl.class.getName()); assertTrue(actual); } finally {