r235 - in trunk: . tutti-persistence tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/entities tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/synchro tutti-persistence-adagio tutti-persistence-adagio/src/main/java/fr/ifremer/tutti/persistence/config tutti-persistence-adagio/src/main/java/fr/ifremer/tutti/persistence/service tutti-persistence-adagio/src/main/java/fr/ifremer/tutti/persistence
Author: tchemit Date: 2013-01-20 16:57:06 +0100 (Sun, 20 Jan 2013) New Revision: 235 Url: http://forge.codelutin.com/projects/tutti/repository/revisions/235 Log: refs #1874: [IMP/EXP] - Synchronisation de r?\195?\169f?\195?\169rentiel (debut) Added: trunk/tutti-persistence-adagio/src/main/java/fr/ifremer/tutti/persistence/service/synchro/ trunk/tutti-persistence-adagio/src/main/java/fr/ifremer/tutti/persistence/service/synchro/ReferentialSynchronizeServiceImpl.java trunk/tutti-persistence-adagio/src/test/java/fr/ifremer/tutti/persistence/service/synchro/ trunk/tutti-persistence-adagio/src/test/java/fr/ifremer/tutti/persistence/service/synchro/ReferentialSynchronizeServiceImplTest.java trunk/tutti-persistence-adagio/src/test/startServerNew.sh trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/synchro/ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/synchro/ReferentialSynchronizeService.java trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/synchro/TableToSynchronize.java trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/synchro/TuttiDatabaseMetadata.java trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/synchro/TuttiTable.java trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/synchro/TuttiTableMetadata.java Modified: trunk/pom.xml trunk/tutti-persistence-adagio/pom.xml trunk/tutti-persistence-adagio/src/main/java/fr/ifremer/tutti/persistence/config/TuttiPersistenceAdagioProvider.java trunk/tutti-persistence-adagio/src/main/java/fr/ifremer/tutti/persistence/service/TuttiPersistenceServiceLocator.java trunk/tutti-persistence-adagio/src/test/java/fr/ifremer/tutti/persistence/DatabaseResource.java trunk/tutti-persistence-adagio/src/test/resources/tutti-test.properties trunk/tutti-persistence-adagio/src/test/startServer.sh trunk/tutti-persistence-dev/src/main/java/fr/ifremer/tutti/persistence/config/TopiaPersistenceDevConfigProvider.java trunk/tutti-persistence/pom.xml trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/entities/TuttiEntities.java trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/DecoratorService.java Modified: trunk/pom.xml =================================================================== --- trunk/pom.xml 2013-01-19 11:46:29 UTC (rev 234) +++ trunk/pom.xml 2013-01-20 15:57:06 UTC (rev 235) @@ -160,6 +160,7 @@ <slf4j.version>1.6.1</slf4j.version> <ehcache.version>2.3.0</ehcache.version> <javassist.version>3.12.1.GA</javassist.version> + <hsqldb.version>2.2.9</hsqldb.version> <jdbc.hsqldb.version>1.8.0.7</jdbc.hsqldb.version> </properties> @@ -396,6 +397,12 @@ </dependency> <dependency> + <groupId>org.hsqldb</groupId> + <artifactId>hsqldb</artifactId> + <version>${hsqldb.version}</version> + </dependency> + + <dependency> <groupId>com.esotericsoftware.yamlbeans</groupId> <artifactId>yamlbeans</artifactId> <version>1.06</version> Modified: trunk/tutti-persistence/pom.xml =================================================================== --- trunk/tutti-persistence/pom.xml 2013-01-19 11:46:29 UTC (rev 234) +++ trunk/tutti-persistence/pom.xml 2013-01-20 15:57:06 UTC (rev 235) @@ -66,8 +66,15 @@ <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> + <scope>provided</scope> </dependency> + <dependency> + <groupId>org.hibernate</groupId> + <artifactId>hibernate-core</artifactId> + <scope>provided</scope> + </dependency> + </dependencies> <build> Modified: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/entities/TuttiEntities.java =================================================================== --- trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/entities/TuttiEntities.java 2013-01-19 11:46:29 UTC (rev 234) +++ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/entities/TuttiEntities.java 2013-01-20 15:57:06 UTC (rev 235) @@ -33,7 +33,12 @@ import fr.ifremer.tutti.persistence.entities.data.FishingOperationAware; import fr.ifremer.tutti.persistence.entities.referential.Caracteristic; import fr.ifremer.tutti.persistence.entities.referential.CaracteristicType; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.Statement; import java.util.Collection; import java.util.Collections; import java.util.List; @@ -47,6 +52,9 @@ */ public class TuttiEntities { + /** Logger. */ + private static final Log log = LogFactory.getLog(TuttiEntities.class); + protected TuttiEntities() { // helper class does not instanciate } @@ -96,6 +104,37 @@ return result; } + public static void closeSilently(Statement statement) { + try { + if (statement != null && !statement.isClosed()) { + + statement.close(); + } + } catch (AbstractMethodError e) { + if (log.isWarnEnabled()) { + log.warn("Fix this linkage error, damned spring :("); + } + } catch (SQLException e) { + if (log.isErrorEnabled()) { + log.error("Could not close statement, but do not care", e); + } + } + } + + public static void closeSilently(Connection connection) { + try { + if (connection != null && !connection.isClosed()) { + + connection.close(); + + } + } catch (SQLException e) { + if (log.isErrorEnabled()) { + log.error("Could not close connection, but do not care", e); + } + } + } + protected static class IdPredicate<B extends IdAware> implements Predicate<B> { private final String id; Added: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/synchro/ReferentialSynchronizeService.java =================================================================== --- trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/synchro/ReferentialSynchronizeService.java (rev 0) +++ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/synchro/ReferentialSynchronizeService.java 2013-01-20 15:57:06 UTC (rev 235) @@ -0,0 +1,120 @@ +package fr.ifremer.tutti.persistence.service.synchro; + +/* + * #%L + * Tutti :: Persistence API + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2012 - 2013 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import org.hibernate.dialect.Dialect; +import org.springframework.dao.DataRetrievalFailureException; +import org.springframework.transaction.annotation.Transactional; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Date; + +/** + * Servide to synchronize referential. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.0 + */ +@Transactional(readOnly = true) +public interface ReferentialSynchronizeService { + + /** + * Load the internal datasource schema to synchronize. + * + * @return the internal datasource schema + * @see TuttiTableMetadata + */ + TuttiDatabaseMetadata loadInternalDb(); + + /** + * Load the datasource schema for the given connectionand internla dialect. + * + * @param connection connection of the data source + * @return the datasource schema + */ + TuttiDatabaseMetadata loadExternalDb(Connection connection); + + /** + * Load the datasource schema for the given connection and dialect. + * + * @param connection connection of the data source + * @param dialect dialect to use + * @return the datasource schema + */ + TuttiDatabaseMetadata loadExternalDb(Connection connection, + Dialect dialect); + + /** + * Check that the tow given datasource shemas are compatible for a + * synchronize operation (same tables with same columns). + * <p/> + * If schemas are incompatible, then a + * {@link DataRetrievalFailureException} exception will be thrown. + * + * @param schema1 schema 1 to check + * @param schema2 shcema 2 to check + */ + void checkSchemas(TuttiDatabaseMetadata schema1, + TuttiDatabaseMetadata schema2); + + /** + * Gets the internal data source dialect. + * + * @return the dialect used by internal datasource. + */ + Dialect getInternalDialect(); + + /** + * Gets the last updateDate for the given {@code table} of the internal datasource. + * + * @param table the table to query + * @param schema the db schema + * @return the last update date of the given table, or {@code null} + * if table does not use a updateDate columns or if there + * is no data in table. + */ + Date getLastUpdateDate(TableToSynchronize table, + TuttiDatabaseMetadata schema) throws SQLException; + + /** + * Gets the last updateDate for the given {@code table} using + * the given datasource + * + * @param connection connection to data source to query + * @param table the table to query + * @param schema the db schema + * @return the last update date of the given table, or {@code null} + * if table does not use a updateDate columns or if there + * is no data in table. + */ + Date getLastUpdateDate(Connection connection, + TableToSynchronize table, + TuttiDatabaseMetadata schema) throws SQLException; + + ResultSet getDataToUpdate(TableToSynchronize table, + TuttiDatabaseMetadata schema, Date fromDate); +} Property changes on: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/synchro/ReferentialSynchronizeService.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/synchro/TableToSynchronize.java =================================================================== --- trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/synchro/TableToSynchronize.java (rev 0) +++ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/synchro/TableToSynchronize.java 2013-01-20 15:57:06 UTC (rev 235) @@ -0,0 +1,118 @@ +package fr.ifremer.tutti.persistence.service.synchro; + +/* + * #%L + * Tutti :: Persistence API + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2012 - 2013 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import org.hibernate.tool.hbm2ddl.ColumnMetadata; + +import java.io.Serializable; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.Date; + +/** + * Define a table to synch. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.0 + */ +public class TableToSynchronize implements Serializable { + + public static final String PK_ID = "id"; + + public static final String PK_CODE = "code"; + + public static final String UPDATE_DATE = "updateDate"; + + private static final long serialVersionUID = 1L; + + public static TableToSynchronize newCode(String tableName) { + return newCode(tableName, true); + } + + public static TableToSynchronize newCode(String tableName, boolean updatable) { + return new TableToSynchronize(tableName, PK_CODE, updatable); + } + + public static TableToSynchronize newId(String tableName) { + return newId(tableName, true); + } + + public static TableToSynchronize newId(String tableName, boolean updatable) { + return new TableToSynchronize(tableName, PK_ID, updatable); + } + + /** + * Name of the table. + * + * @since 1.0 + */ + protected final String tableName; + + /** + * Name of the column which acts as primary key. + * + * @since 1.0 + */ + protected final String pkColumnName; + + /** + * Optional restrict condition to add on query to select data to synchronize. + * + * @since 1.0 + */ + protected final boolean withUpdateColumn; + + public TableToSynchronize(String tableName, + String pkColumnName, + boolean withUpdateColumn) { + this.tableName = tableName; + this.pkColumnName = pkColumnName; + this.withUpdateColumn = withUpdateColumn; + } + + public void addRestrictFilter(PreparedStatement statement, + TuttiTableMetadata meta, + Date date) throws SQLException { + ColumnMetadata updateDate = meta.getColumnMetadata(UPDATE_DATE); + if (updateDate != null) { + + // can add a filteron updateDate column + int columnsCount = meta.getColumnsCount(); + statement.setDate(columnsCount + 1, new java.sql.Date(date.getTime())); + } + } + + public String getTableName() { + return tableName; + } + + public String getPkColumnName() { + return pkColumnName; + } + + public boolean isWithUpdateColumn() { + return withUpdateColumn; + } +} Property changes on: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/synchro/TableToSynchronize.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/synchro/TuttiDatabaseMetadata.java =================================================================== --- trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/synchro/TuttiDatabaseMetadata.java (rev 0) +++ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/synchro/TuttiDatabaseMetadata.java 2013-01-20 15:57:06 UTC (rev 235) @@ -0,0 +1,100 @@ +package fr.ifremer.tutti.persistence.service.synchro; + +/* + * #%L + * Tutti :: Persistence API + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2012 - 2013 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import com.google.common.base.Preconditions; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import org.hibernate.HibernateException; +import org.hibernate.dialect.Dialect; +import org.hibernate.mapping.Table; +import org.hibernate.tool.hbm2ddl.DatabaseMetadata; +import org.hibernate.tool.hbm2ddl.TableMetadata; + +import java.sql.Connection; +import java.sql.SQLException; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +/** + * TODO + * + * @author tchemit <chemit@codelutin.com> + * @since 1.0 + */ +public class TuttiDatabaseMetadata { + + protected final DatabaseMetadata delegate; + + protected Map<String, TuttiTableMetadata> tables; + + public TuttiDatabaseMetadata(Connection connection, Dialect dialect) { + Preconditions.checkNotNull(connection); + Preconditions.checkNotNull(dialect); + try { + this.delegate = new DatabaseMetadata(connection, dialect, true); + } catch (SQLException e) { + throw new RuntimeException( + "Could not init database meta on connection " + connection, e); + } + tables = Maps.newTreeMap(); + } + + public TuttiTableMetadata getTable(String name) throws HibernateException { + return getTable(name, "PUBLIC", null, false); + } + + public int getTableCount() { + return tables.size(); + } + + public Set<String> getTableNames() { + HashSet<String> result = Sets.newHashSet(); + for (TuttiTableMetadata tableMetadata : tables.values()) { + result.add(tableMetadata.getName()); + } + return result; + } + + protected TuttiTableMetadata getTable(String name, + String schema, + String catalog, + boolean isQuoted) throws HibernateException { + String key = Table.qualify(catalog, schema, name); + TuttiTableMetadata tuttiTableMetadata = tables.get(key); + if (tuttiTableMetadata == null) { + + TableMetadata tableMetadata = delegate.getTableMetadata(name, schema, catalog, isQuoted); + Preconditions.checkNotNull(tableMetadata, + "Could not find db table " + name); + tuttiTableMetadata = new TuttiTableMetadata(tableMetadata); + Preconditions.checkNotNull(tuttiTableMetadata, + "Could not find db table " + name); + tables.put(key, tuttiTableMetadata); + } + return tuttiTableMetadata; + } +} Property changes on: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/synchro/TuttiDatabaseMetadata.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/synchro/TuttiTable.java =================================================================== --- trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/synchro/TuttiTable.java (rev 0) +++ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/synchro/TuttiTable.java 2013-01-20 15:57:06 UTC (rev 235) @@ -0,0 +1,105 @@ +package fr.ifremer.tutti.persistence.service.synchro; + +/* + * #%L + * Tutti :: Persistence API + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2012 - 2013 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +/** + * TODO + * + * @author tchemit <chemit@codelutin.com> + * @since 1.0 + */ +public enum TuttiTable { + STATUS(TableToSynchronize.newCode("STATUS", false)), + QUALITY_FLAG(TableToSynchronize.newCode("QUALITY_FLAG", false)), + + // PMFM + UNIT, + AGGREGATION_LEVEL, + PARAMETER_GROUP, + QUALITATIVE_VALUE(false), + PARAMETER, + MATRIX, + FRACTION, + METHOD, + PMFM, + + // GEAR + GEAR_CLASSIFICATION, + GEAR, + + // LOCATION + LOCATION_CLASSIFICATION, + LOCATION_LEVEL, + //TODO Association LOCATIONAssociation(TableToSynchronize.newId("LOCATIONAssociation")), + LOCATION, +//TODO Association LOCATIONHierarchy(TableToSynchronize.newId("LOCATIONHierarchy")), +//TODO Association LOCATIONHierarchyException(TableToSynchronize.newId("LOCATIONHierarchyException")), + + // TAXON + TAXONOMIC_LEVEL, + REFERENCE_TAXON, + TAXON_NAME, + + // TAXON GROUP + TAXON_GROUP_TYPE, + TAXON_GROUP, + + // CONVERSION + ROUND_WEIGHT_CONVERSION, + WEIGHT_LENGTH_CONVERSION, + + // VESSEL + VESSEL_TYPE, + //TODO Association VESSEL_REGISTRATION_PERIOD(false), +// VESSEL_FLEET_EVENT, + VESSEL, + + // FEATURES + GEAR_PHYSICAL_FEATURES, + VESSEL_PHYSICAL_FEATURES, + + USER_PROFIL, + DEPARTMENT, + PERSON, + ; + + private final TableToSynchronize meta; + + private TuttiTable() { + this(true); + } + + private TuttiTable(boolean updatable) { + this.meta = TableToSynchronize.newId(name(), updatable); + } + + private TuttiTable(TableToSynchronize meta) { + this.meta = meta; + } + + public TableToSynchronize getMeta() { + return meta; + } +} Property changes on: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/synchro/TuttiTable.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/synchro/TuttiTableMetadata.java =================================================================== --- trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/synchro/TuttiTableMetadata.java (rev 0) +++ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/synchro/TuttiTableMetadata.java 2013-01-20 15:57:06 UTC (rev 235) @@ -0,0 +1,100 @@ +package fr.ifremer.tutti.persistence.service.synchro; + +/* + * #%L + * Tutti :: Persistence API + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2012 - 2013 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import com.google.common.base.Preconditions; +import com.google.common.collect.Sets; +import org.hibernate.mapping.ForeignKey; +import org.hibernate.tool.hbm2ddl.ColumnMetadata; +import org.hibernate.tool.hbm2ddl.ForeignKeyMetadata; +import org.hibernate.tool.hbm2ddl.IndexMetadata; +import org.hibernate.tool.hbm2ddl.TableMetadata; + +import java.lang.reflect.Field; +import java.util.Map; +import java.util.Set; + +/** + * TODO + * + * @author tchemit <chemit@codelutin.com> + * @since TODO + */ +public class TuttiTableMetadata { + + protected final TableMetadata delegate; + + protected Map<String, ColumnMetadata> columns; + + public TuttiTableMetadata(TableMetadata delegate) { + + Preconditions.checkNotNull(delegate); + this.delegate = delegate; + + try { + Field field = TableMetadata.class.getDeclaredField("columns"); + field.setAccessible(true); + columns = (Map) field.get(delegate); + } catch (Exception e) { + throw new RuntimeException("Could not init " + this, e); + } + } + + public int getColumnsCount() { + return columns.size(); + } + + public Set<String> getColumnNames() { + return Sets.newHashSet(columns.keySet()); + } + + public String getName() { + return delegate.getName(); + } + + public ForeignKeyMetadata getForeignKeyMetadata(ForeignKey fk) { + return delegate.getForeignKeyMetadata(fk); + } + + public ColumnMetadata getColumnMetadata(String columnName) { + return delegate.getColumnMetadata(columnName); + } + + public String getSchema() { + return delegate.getSchema(); + } + + public String getCatalog() { + return delegate.getCatalog(); + } + + public ForeignKeyMetadata getForeignKeyMetadata(String keyName) { + return delegate.getForeignKeyMetadata(keyName); + } + + public IndexMetadata getIndexMetadata(String indexName) { + return delegate.getIndexMetadata(indexName); + } +} Property changes on: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/synchro/TuttiTableMetadata.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Modified: trunk/tutti-persistence-adagio/pom.xml =================================================================== --- trunk/tutti-persistence-adagio/pom.xml 2013-01-19 11:46:29 UTC (rev 234) +++ trunk/tutti-persistence-adagio/pom.xml 2013-01-20 15:57:06 UTC (rev 235) @@ -156,6 +156,11 @@ <artifactId>spring-test</artifactId> </dependency> + <!--dependency> + <groupId>org.hsqldb</groupId> + <artifactId>hsqldb</artifactId> + </dependency--> + <dependency> <groupId>hsqldb</groupId> <artifactId>hsqldb</artifactId> Modified: trunk/tutti-persistence-adagio/src/main/java/fr/ifremer/tutti/persistence/config/TuttiPersistenceAdagioProvider.java =================================================================== --- trunk/tutti-persistence-adagio/src/main/java/fr/ifremer/tutti/persistence/config/TuttiPersistenceAdagioProvider.java 2013-01-19 11:46:29 UTC (rev 234) +++ trunk/tutti-persistence-adagio/src/main/java/fr/ifremer/tutti/persistence/config/TuttiPersistenceAdagioProvider.java 2013-01-20 15:57:06 UTC (rev 235) @@ -39,12 +39,12 @@ @Override public String getName() { - return "tutti-adagio-persistence"; + return "tutti-persistence-adagio"; } @Override public String getDescription(Locale locale) { - return "Configuration de la persistence de Tutti (Adagio implantation)."; + return "Configuration de la persistence de Tutti (implantation via Adagio)."; } @Override Modified: trunk/tutti-persistence-adagio/src/main/java/fr/ifremer/tutti/persistence/service/TuttiPersistenceServiceLocator.java =================================================================== --- trunk/tutti-persistence-adagio/src/main/java/fr/ifremer/tutti/persistence/service/TuttiPersistenceServiceLocator.java 2013-01-19 11:46:29 UTC (rev 234) +++ trunk/tutti-persistence-adagio/src/main/java/fr/ifremer/tutti/persistence/service/TuttiPersistenceServiceLocator.java 2013-01-20 15:57:06 UTC (rev 235) @@ -26,6 +26,7 @@ import fr.ifremer.adagio.core.service.ServiceLocator; import fr.ifremer.tutti.persistence.TuttiPersistence; +import fr.ifremer.tutti.persistence.service.synchro.ReferentialSynchronizeService; /** * To obtain services from spring context. @@ -111,4 +112,9 @@ public static void close() { instance().shutdown(); } + + public static ReferentialSynchronizeService getReferentialSynchronizeService() { + return instance().getService("referentialSynchronizeService", + ReferentialSynchronizeService.class); + } } Added: trunk/tutti-persistence-adagio/src/main/java/fr/ifremer/tutti/persistence/service/synchro/ReferentialSynchronizeServiceImpl.java =================================================================== --- trunk/tutti-persistence-adagio/src/main/java/fr/ifremer/tutti/persistence/service/synchro/ReferentialSynchronizeServiceImpl.java (rev 0) +++ trunk/tutti-persistence-adagio/src/main/java/fr/ifremer/tutti/persistence/service/synchro/ReferentialSynchronizeServiceImpl.java 2013-01-20 15:57:06 UTC (rev 235) @@ -0,0 +1,170 @@ +package fr.ifremer.tutti.persistence.service.synchro; + +/* + * #%L + * Tutti :: Persistence Adagio (impl) + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2012 - 2013 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import fr.ifremer.tutti.persistence.entities.TuttiEntities; +import fr.ifremer.tutti.persistence.service.AbstractPersistenceService; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.hibernate.classic.Session; +import org.hibernate.dialect.Dialect; +import org.hibernate.engine.SessionFactoryImplementor; +import org.hibernate.tool.hbm2ddl.ColumnMetadata; +import org.springframework.dao.DataRetrievalFailureException; +import org.springframework.stereotype.Service; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Date; +import java.util.Set; + +/** + * TODO + * + * @author tchemit <chemit@codelutin.com> + * @since 1.0 + */ +@Service("referentialSynchronizeService") +public class ReferentialSynchronizeServiceImpl extends AbstractPersistenceService implements ReferentialSynchronizeService { + + /** Logger. */ + private static final Log log = + LogFactory.getLog(ReferentialSynchronizeServiceImpl.class); + + public static final String QUERY_SELECT_MAX_UPDATE = "SELECT max(update_date) FROM %s"; + + protected Dialect dialect; + + @Override + public TuttiDatabaseMetadata loadInternalDb() { + Connection connection = getConnection(); + + return loadExternalDb(connection, getInternalDialect()); + } + + private Connection getConnection() { + Session session = getCurrentSession(); + return session.connection(); + } + + @Override + public TuttiDatabaseMetadata loadExternalDb(Connection connection) { + return loadExternalDb(connection, getInternalDialect()); + } + + @Override + public TuttiDatabaseMetadata loadExternalDb(Connection connection, + Dialect dialect) { + TuttiDatabaseMetadata result = new TuttiDatabaseMetadata(connection, dialect); + for (TuttiTable tuttiTable : TuttiTable.values()) { + + TableToSynchronize meta = tuttiTable.getMeta(); + String tableName = meta.getTableName(); + if (log.isDebugEnabled()) { + log.debug("Load metas of table: " + tableName); + } + result.getTable(tableName); + } + return result; + } + + @Override + public void checkSchemas(TuttiDatabaseMetadata schema1, + TuttiDatabaseMetadata schema2) { + Set<String> internalSchemaTableNames = schema1.getTableNames(); + Set<String> externalSchemaTableNames = schema2.getTableNames(); + if (!internalSchemaTableNames.equals(externalSchemaTableNames)) { + throw new DataRetrievalFailureException("Incompatible schemas"); + } + for (String tableName : internalSchemaTableNames) { + TuttiTableMetadata internalTable = schema1.getTable(tableName); + TuttiTableMetadata externalTable = schema2.getTable(tableName); + Set<String> internalColumnNames = internalTable.getColumnNames(); + Set<String> externalColumnNames = externalTable.getColumnNames(); + if (!internalColumnNames.equals(externalColumnNames)) { + throw new DataRetrievalFailureException("Incompatible schema of table: " + tableName); + } + for (String columnName : internalColumnNames) { + ColumnMetadata internalColumn = internalTable.getColumnMetadata(columnName); + ColumnMetadata externalColumn = externalTable.getColumnMetadata(columnName); + String internalColumnTypeName = internalColumn.getTypeName(); + String externalColumnTypeName = externalColumn.getTypeName(); + if (!internalColumnTypeName.equals(externalColumnTypeName)) { + throw new DataRetrievalFailureException("Incompatible column type of table / column: " + tableName + " / " + columnName); + } + } + } + } + + @Override + public Dialect getInternalDialect() { + if (dialect == null) { + dialect = ((SessionFactoryImplementor) sessionFactory).getSettings().getDialect(); + } + return dialect; + } + + @Override + public Date getLastUpdateDate(TableToSynchronize table, + TuttiDatabaseMetadata schema) throws SQLException { + + Date result = getLastUpdateDate(getConnection(), table, schema); + return result; + } + + @Override + public Date getLastUpdateDate(Connection connection, TableToSynchronize table, + TuttiDatabaseMetadata schema) throws SQLException { + Date result = null; + + if (table.isWithUpdateColumn()) { + + TuttiTableMetadata tableMeta = schema.getTable(table.getTableName()); + + String sql = String.format(QUERY_SELECT_MAX_UPDATE, tableMeta.getName()); + + PreparedStatement statement = connection.prepareStatement(sql); + try { + ResultSet resultSet = statement.executeQuery(); + if (resultSet.next()) { + result = resultSet.getDate(1); + } + statement.close(); + } finally { + TuttiEntities.closeSilently(statement); + } + } + return result; + } + + @Override + public ResultSet getDataToUpdate(TableToSynchronize table, + TuttiDatabaseMetadata schema, Date fromDate) { + return null; + } + +} Property changes on: trunk/tutti-persistence-adagio/src/main/java/fr/ifremer/tutti/persistence/service/synchro/ReferentialSynchronizeServiceImpl.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Modified: trunk/tutti-persistence-adagio/src/test/java/fr/ifremer/tutti/persistence/DatabaseResource.java =================================================================== --- trunk/tutti-persistence-adagio/src/test/java/fr/ifremer/tutti/persistence/DatabaseResource.java 2013-01-19 11:46:29 UTC (rev 234) +++ trunk/tutti-persistence-adagio/src/test/java/fr/ifremer/tutti/persistence/DatabaseResource.java 2013-01-20 15:57:06 UTC (rev 235) @@ -24,6 +24,12 @@ * #L% */ +import com.google.common.base.Charsets; +import com.google.common.base.Preconditions; +import com.google.common.base.Predicate; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import com.google.common.io.Files; import fr.ifremer.tutti.persistence.config.TuttiPersistenceAdagioConfig; import fr.ifremer.tutti.persistence.config.TuttiPersistenceAdagioConfigOption; import fr.ifremer.tutti.persistence.service.TuttiPersistenceServiceLocator; @@ -38,6 +44,12 @@ import java.io.File; import java.io.IOException; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.List; +import java.util.Set; /** * To box the persistence service as a test resource. @@ -50,14 +62,18 @@ /** Logger. */ private static final Log log = LogFactory.getLog(DatabaseResource.class); + public static final String TUTTI_PERSISTENCE_JDBC_CREATE_SCRIPT = "tutti.persistence.jdbc.createScript"; + public static long BUILD_TIMESTAMP = System.nanoTime(); private static ClassLoader oldClassLoader; - protected TuttiPersistenceAdagioConfig config; + private File resourceDirectory; - protected DatabaseFixtures fixtures; + private TuttiPersistenceAdagioConfig config; + private DatabaseFixtures fixtures; + private final String beanFactoryReferenceLocation; private final String beanRefFactoryReferenceId; @@ -80,6 +96,10 @@ return fixtures; } + public File getResourceDirectory(String name) { + return new File(resourceDirectory, name); + } + @Override public Statement apply(final Statement base, final Description description) { @@ -115,7 +135,7 @@ fixtures = new DatabaseFixtures(); - File resourceDirectory = getTestSpecificDirectory(testClass, ""); + resourceDirectory = getTestSpecificDirectory(testClass, ""); RessourceClassLoader loader = new RessourceClassLoader(testClass.getClassLoader()); @@ -165,6 +185,12 @@ } } + public Connection createEmptyDb(String dbDirectory, + String dbName) throws IOException, SQLException { + File externalDbFile = getResourceDirectory(dbDirectory); + return createEmptyDb(externalDbFile, dbName); + } + public static File getTestSpecificDirectory(Class<?> testClass, String name) throws IOException { // Trying to look for the temporary folder to store data for the test @@ -189,4 +215,70 @@ return databaseFile; } + + public Connection createEmptyDb(File directory, + String dbName) throws SQLException, IOException { + + if (log.isInfoEnabled()) { + log.info("Create new db at " + directory); + } + String jdbcUrl = "jdbc:hsqldb:file:" + directory.getAbsolutePath() + "/" + dbName; + String user = "SA"; + String password = ""; + + File scriptFile = config.getConfig().getOptionAsFile(TUTTI_PERSISTENCE_JDBC_CREATE_SCRIPT); + + Preconditions.checkNotNull("Could not find db script in configuration with key " + TUTTI_PERSISTENCE_JDBC_CREATE_SCRIPT); + Preconditions.checkState(scriptFile.exists(), "Could not find db script at " + scriptFile); + + if (log.isInfoEnabled()) { + log.info("Will use create script: " + scriptFile); + } + Connection connection = DriverManager.getConnection(jdbcUrl, user, password); + + if (log.isInfoEnabled()) { + log.info("Created connection at " + connection.getMetaData().getURL()); + } + + List<String> importScriptSql = getImportScriptSql(scriptFile); + for (String sql : importScriptSql) { + PreparedStatement statement = connection.prepareStatement(sql); + statement.execute(); + } + connection.commit(); + return connection; + } + + protected List<String> getImportScriptSql(File scriptFile) throws IOException { + List<String> lines = Files.readLines(scriptFile, Charsets.UTF_8); + + List<String> result = Lists.newArrayListWithCapacity(lines.size()); + + Predicate<String> predicate = new Predicate<String>() { + + Set<String> forbiddenStarts = Sets.newHashSet( + "SET ", + "CREATE USER ", + "CREATE SCHEMA ", + "GRANT DBA TO "); + + @Override + public boolean apply(String input) { + boolean accept = true; + for (String forbiddenStart : forbiddenStarts) { + if (input.startsWith(forbiddenStart)) { + accept = false; + break; + } + } + return accept; + } + }; + for (String line : lines) { + if (predicate.apply(line.trim().toUpperCase())) { + result.add(line); + } + } + return result; + } } Added: trunk/tutti-persistence-adagio/src/test/java/fr/ifremer/tutti/persistence/service/synchro/ReferentialSynchronizeServiceImplTest.java =================================================================== --- trunk/tutti-persistence-adagio/src/test/java/fr/ifremer/tutti/persistence/service/synchro/ReferentialSynchronizeServiceImplTest.java (rev 0) +++ trunk/tutti-persistence-adagio/src/test/java/fr/ifremer/tutti/persistence/service/synchro/ReferentialSynchronizeServiceImplTest.java 2013-01-20 15:57:06 UTC (rev 235) @@ -0,0 +1,232 @@ +package fr.ifremer.tutti.persistence.service.synchro; + +/* + * #%L + * Tutti :: Persistence Adagio (impl) + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2012 - 2013 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import fr.ifremer.tutti.persistence.DatabaseResource; +import fr.ifremer.tutti.persistence.service.TuttiPersistenceServiceLocator; +import org.apache.commons.lang3.time.DateUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.hibernate.dialect.Dialect; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Ignore; +import org.junit.Test; +import org.springframework.dao.DataRetrievalFailureException; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.Calendar; +import java.util.Date; + +/** + * @author tchemit <chemit@codelutin.com> + * @since 1.0 + */ +public class ReferentialSynchronizeServiceImplTest { + + /** Logger. */ + private static final Log log = + LogFactory.getLog(ReferentialSynchronizeServiceImplTest.class); + + @ClassRule + public static final DatabaseResource dbResource = new DatabaseResource(); + + protected ReferentialSynchronizeService service; + + protected Connection externalConnection; + + @Before + public void setUp() throws Exception { + service = TuttiPersistenceServiceLocator.getReferentialSynchronizeService(); + } + + @After + public void tearDown() throws Exception { + service = null; + if (externalConnection != null) { + if (!externalConnection.isClosed()) { + externalConnection.close(); + } + externalConnection = null; + } + } + + @Test + public void loadInternalDb() throws Exception { + + Dialect dialect = service.getInternalDialect(); + Assert.assertNotNull(dialect); + + TuttiDatabaseMetadata tuttiDatabaseMetadata = service.loadInternalDb(); + Assert.assertNotNull(tuttiDatabaseMetadata); + } + + @Test + public void checkSchemas() throws Exception { + + TuttiDatabaseMetadata internalDb = service.loadInternalDb(); + Assert.assertNotNull(internalDb); + service.checkSchemas(internalDb, internalDb); + + // create a external empty db + externalConnection = dbResource.createEmptyDb("checkSchemas", "newDb"); + Assert.assertNotNull(externalConnection); + + TuttiDatabaseMetadata externalDb = service.loadExternalDb(externalConnection); + Assert.assertNotNull(externalDb); + service.checkSchemas(internalDb, externalDb); + + // add a column in a table and recheck schemas + PreparedStatement statement = externalConnection.prepareStatement("ALTER TABLE PUBLIC.LOCATION ADD newColumn" + System.nanoTime() + " int NOT NULL;"); + statement.execute(); + externalConnection.commit(); + + try { + // reload external schema, it has changed + externalDb = service.loadExternalDb(externalConnection); + + service.checkSchemas(internalDb, externalDb); + Assert.fail(); + } catch (DataRetrievalFailureException e) { + + Assert.assertTrue(true); + } + } + + @Test + public void getLastUpdateDate() throws Exception { + + TuttiDatabaseMetadata internalDb = service.loadInternalDb(); + Assert.assertNotNull(internalDb); + + getLastUpdateDate(TuttiTable.STATUS, internalDb, null); + getLastUpdateDate(TuttiTable.QUALITY_FLAG, internalDb, null); + getLastUpdateDate(TuttiTable.UNIT, internalDb, getSqlDate(2012, 8, 17)); + getLastUpdateDate(TuttiTable.AGGREGATION_LEVEL, internalDb, getSqlDate(2011, 6, 9)); + getLastUpdateDate(TuttiTable.PARAMETER_GROUP, internalDb, getSqlDate(2012, 10, 5)); + getLastUpdateDate(TuttiTable.QUALITATIVE_VALUE, internalDb, null); + getLastUpdateDate(TuttiTable.PARAMETER, internalDb, getSqlDate(2012, 11, 13)); + getLastUpdateDate(TuttiTable.MATRIX, internalDb, getSqlDate(2012, 8, 13)); + getLastUpdateDate(TuttiTable.FRACTION, internalDb, getSqlDate(2011, 12, 21)); + getLastUpdateDate(TuttiTable.METHOD, internalDb, getSqlDate(2012, 9, 28)); + getLastUpdateDate(TuttiTable.PMFM, internalDb, getSqlDate(2012, 11, 13)); + getLastUpdateDate(TuttiTable.GEAR_CLASSIFICATION, internalDb, getSqlDate(2012, 11, 15)); + getLastUpdateDate(TuttiTable.GEAR, internalDb, getSqlDate(2012, 11, 22)); + getLastUpdateDate(TuttiTable.LOCATION_CLASSIFICATION, internalDb, getSqlDate(2010, 10, 26)); + getLastUpdateDate(TuttiTable.LOCATION_LEVEL, internalDb, getSqlDate(2012, 11, 22)); + getLastUpdateDate(TuttiTable.LOCATION, internalDb, getSqlDate(2012, 11, 22)); + getLastUpdateDate(TuttiTable.TAXONOMIC_LEVEL, internalDb, getSqlDate(2012, 4, 18)); + getLastUpdateDate(TuttiTable.REFERENCE_TAXON, internalDb, getSqlDate(2012, 11, 15)); + getLastUpdateDate(TuttiTable.TAXON_NAME, internalDb, getSqlDate(2012, 11, 15)); + getLastUpdateDate(TuttiTable.TAXON_GROUP_TYPE, internalDb, getSqlDate(2012, 5, 24)); + getLastUpdateDate(TuttiTable.TAXON_GROUP, internalDb, getSqlDate(2012, 9, 12)); + getLastUpdateDate(TuttiTable.ROUND_WEIGHT_CONVERSION, internalDb, getSqlDate(2012, 10, 4)); + getLastUpdateDate(TuttiTable.WEIGHT_LENGTH_CONVERSION, internalDb, getSqlDate(2012, 10, 23)); + getLastUpdateDate(TuttiTable.VESSEL_TYPE, internalDb, getSqlDate(2012, 4, 25)); + getLastUpdateDate(TuttiTable.VESSEL, internalDb, getSqlDate(2012, 11, 22)); + getLastUpdateDate(TuttiTable.GEAR_PHYSICAL_FEATURES, internalDb, getSqlDate(2012, 11, 22)); + getLastUpdateDate(TuttiTable.VESSEL_PHYSICAL_FEATURES, internalDb, null); + getLastUpdateDate(TuttiTable.USER_PROFIL, internalDb, getSqlDate(2009, 6, 18)); + getLastUpdateDate(TuttiTable.DEPARTMENT, internalDb, getSqlDate(2012, 11, 15)); + getLastUpdateDate(TuttiTable.PERSON, internalDb, getSqlDate(2012, 11, 30)); + + // try it on a empty db (all values are to null) + + // create a external empty db + externalConnection = dbResource.createEmptyDb("getLastUpdateDate", "newDb"); + Assert.assertNotNull(externalConnection); + + TuttiDatabaseMetadata externalDb = + service.loadExternalDb(externalConnection); + + for (TuttiTable tuttiTable : TuttiTable.values()) { + getLastUpdateDate(tuttiTable, externalDb, true, null); + } + } + + @Ignore + @Test + public void getDataToUpdate() throws SQLException { + + Date fromDate = getDate(2012, 1, 1); + + TuttiDatabaseMetadata internalDb = service.loadInternalDb(); + Assert.assertNotNull(internalDb); + + + } + + protected void getLastUpdateDate(TuttiTable tuttiTable, + TuttiDatabaseMetadata db, + Date expected) throws SQLException { + getLastUpdateDate(tuttiTable, db, false, expected); + } + + protected void getLastUpdateDate(TuttiTable tuttiTable, + TuttiDatabaseMetadata db, + boolean external, + Date expected) throws SQLException { + + Date actual; + if (external) { + actual = service.getLastUpdateDate(externalConnection, + tuttiTable.getMeta(), db); + } else { + actual = service.getLastUpdateDate(tuttiTable.getMeta(), db); + + } + if (expected == null) { + + Assert.assertNull(actual); + } else { + + Calendar expectedCal = Calendar.getInstance(); + expectedCal.setTime(expected); + Calendar actualCal = Calendar.getInstance(); + actualCal.setTime(actual); + Assert.assertEquals(expectedCal.get(Calendar.YEAR), actualCal.get(Calendar.YEAR)); + Assert.assertEquals(expectedCal.get(Calendar.MONTH), actualCal.get(Calendar.MONTH)); + Assert.assertEquals(expectedCal.get(Calendar.DAY_OF_MONTH), actualCal.get(Calendar.DAY_OF_MONTH)); + } + } + + protected Date getSqlDate(int year, int month, int day) { + return getDate(year, month - 1, day); + } + + protected Date getDate(int year, int month, int day) { + Date fromDate = DateUtils.setYears( + DateUtils.setMonths( + DateUtils.setDays(new Date(), day), + month), + year); + return fromDate; + } + +} Property changes on: trunk/tutti-persistence-adagio/src/test/java/fr/ifremer/tutti/persistence/service/synchro/ReferentialSynchronizeServiceImplTest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Modified: trunk/tutti-persistence-adagio/src/test/resources/tutti-test.properties =================================================================== --- trunk/tutti-persistence-adagio/src/test/resources/tutti-test.properties 2013-01-19 11:46:29 UTC (rev 234) +++ trunk/tutti-persistence-adagio/src/test/resources/tutti-test.properties 2013-01-20 15:57:06 UTC (rev 235) @@ -22,4 +22,5 @@ # #L% ### #tutti.persistence.jdbc.url=jdbc:hsqldb:file:src/test/db/allegro -tutti.persistence.jdbc.url=jdbc:hsqldb:hsql://localhost/allegro \ No newline at end of file +tutti.persistence.jdbc.url=jdbc:hsqldb:hsql://localhost/allegro +tutti.persistence.jdbc.createScript=src/test/db/allegro.script Modified: trunk/tutti-persistence-adagio/src/test/startServer.sh =================================================================== --- trunk/tutti-persistence-adagio/src/test/startServer.sh 2013-01-19 11:46:29 UTC (rev 234) +++ trunk/tutti-persistence-adagio/src/test/startServer.sh 2013-01-20 15:57:06 UTC (rev 235) @@ -1,3 +1,3 @@ #! /bin/sh -java -classpath ~/.m2/repository/hsqldb/hsqldb/1.8.0.7/hsqldb-1.8.0.7.jar org.hsqldb.Server --database.0 file:db/allegro --dbname.0 allegro \ No newline at end of file +java -classpath ~/.m2/repository/hsqldb/hsqldb/1.8.0.7/hsqldb-1.8.0.7.jar org.hsqldb.Server --database.0 file:db/allegro --dbname.0 allegro Copied: trunk/tutti-persistence-adagio/src/test/startServerNew.sh (from rev 231, trunk/tutti-persistence-adagio/src/test/startServer.sh) =================================================================== --- trunk/tutti-persistence-adagio/src/test/startServerNew.sh (rev 0) +++ trunk/tutti-persistence-adagio/src/test/startServerNew.sh 2013-01-20 15:57:06 UTC (rev 235) @@ -0,0 +1,3 @@ +#! /bin/sh + +java -classpath ~/.m2/repository/org/hsqldb/hsqldb/2.2.9/hsqldb-2.2.9.jar org.hsqldb.Server --database.0 file:db/allegro --dbname.0 allegro \ No newline at end of file Modified: trunk/tutti-persistence-dev/src/main/java/fr/ifremer/tutti/persistence/config/TopiaPersistenceDevConfigProvider.java =================================================================== --- trunk/tutti-persistence-dev/src/main/java/fr/ifremer/tutti/persistence/config/TopiaPersistenceDevConfigProvider.java 2013-01-19 11:46:29 UTC (rev 234) +++ trunk/tutti-persistence-dev/src/main/java/fr/ifremer/tutti/persistence/config/TopiaPersistenceDevConfigProvider.java 2013-01-20 15:57:06 UTC (rev 235) @@ -39,12 +39,12 @@ @Override public String getName() { - return "tutti-persistence"; + return "tutti-persistence-dev"; } @Override public String getDescription(Locale locale) { - return "Configuration de la persistence de Tutti"; + return "Configuration de la persistence de Tutti (implantation par serialisation)"; } @Override Modified: trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/DecoratorService.java =================================================================== --- trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/DecoratorService.java 2013-01-19 11:46:29 UTC (rev 234) +++ trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/DecoratorService.java 2013-01-20 15:57:06 UTC (rev 235) @@ -39,11 +39,13 @@ import fr.ifremer.tutti.persistence.entities.referential.Species; import fr.ifremer.tutti.persistence.entities.referential.Vessel; import fr.ifremer.tutti.persistence.entities.referential.Zone; -import java.io.Serializable; -import static org.nuiton.i18n.I18n.n_; import org.nuiton.util.decorator.Decorator; import org.nuiton.util.decorator.DecoratorProvider; +import java.io.Serializable; + +import static org.nuiton.i18n.I18n.n_; + /** * Tutti decorator service. * @@ -65,7 +67,7 @@ public static final String SPECIES_BY_CODE = "byCode"; public static final String SPECIES_BY_GENUS = "byGenus"; - + public static final String CARACTERISTIC_WITH_UNIT = "withUnit"; public static final String BY_NAME = "byName";
participants (1)
-
tchemit@users.forge.codelutin.com