From do-not-reply at jboss.org Thu Feb 16 05:59:48 2012 Content-Type: multipart/mixed; boundary="===============3201311250005725456==" MIME-Version: 1.0 From: do-not-reply at jboss.org To: exo-jcr-commits at lists.jboss.org Subject: [exo-jcr-commits] exo-jcr SVN: r5649 - in jcr/branches/1.15.x/exo.jcr.component.core/src: test/java/org/exoplatform/services/jcr/impl and 1 other directory. Date: Thu, 16 Feb 2012 05:59:47 -0500 Message-ID: <201202161059.q1GAxl88030982@svn01.web.mwc.hst.phx2.redhat.com> --===============3201311250005725456== Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Author: andrew.plotnikov Date: 2012-02-16 05:59:46 -0500 (Thu, 16 Feb 2012) New Revision: 5649 Added: jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform= /services/jcr/impl/storage/jdbc/InspectionQuery.java jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform= /services/jcr/impl/storage/jdbc/InspectionQueryFilteredMultivaluedPropertie= s.java Modified: jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform= /services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainerChecker.java jcr/branches/1.15.x/exo.jcr.component.core/src/test/java/org/exoplatform= /services/jcr/impl/TestRepositoryCheckController.java Log: EXOJCR-1755: Improved queries for repository checking consistency Added: jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplat= form/services/jcr/impl/storage/jdbc/InspectionQuery.java =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatfor= m/services/jcr/impl/storage/jdbc/InspectionQuery.java = (rev 0) +++ jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatfor= m/services/jcr/impl/storage/jdbc/InspectionQuery.java 2012-02-16 10:59:46 U= TC (rev 5649) @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2012 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.exoplatform.services.jcr.impl.storage.jdbc; + +import org.exoplatform.services.jcr.impl.InspectionLog.InspectionStatus; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; + +/** + * @author Andrey Plotniko= v + * @version $Id: InspectionQuery.java 34360 16.02.2012 andrew.plotnikov $ + */ +class InspectionQuery +{ + /** + * Data class, contains a combination of SQL states, description, field= names and status = + */ + + /** + * SQL query that must be executed. + */ + public String statement; + + /** + * Inspection query description. + */ + public String description; + + /** + * Field names that must be showed in inspection log if something wrong. + */ + public String[] fieldNames; + + /** + * Corruption status. Is it critical - ERR, or not - WARN. + */ + public InspectionStatus status; + + public InspectionQuery(String statement, String[] fieldNames, String he= aderMessage, InspectionStatus status) + { + this.statement =3D statement; + this.description =3D headerMessage; + this.fieldNames =3D fieldNames; + this.status =3D status; + } + + public String getStatement() + { + return statement; + } + + public String getDescription() + { + return description; + } + + public String[] getFieldNames() + { + return fieldNames; + } + + public InspectionStatus getStatus() + { + return status; + } + + /** + * Creates a PreparedStatement object for sending parameterized SQL sta= tements to the database. = + * = + * @param connection + * connection to workspace storage + * @return + * a new default PreparedStatement object containing the pre-c= ompiled SQL statement = + * @throws SQLException + * if a database access error occurs or this method is called= on a closed connection + */ + public PreparedStatement prepareStatement(Connection connection) throws= SQLException + { + return connection.prepareStatement(statement); + } + +} Added: jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplat= form/services/jcr/impl/storage/jdbc/InspectionQueryFilteredMultivaluedPrope= rties.java =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatfor= m/services/jcr/impl/storage/jdbc/InspectionQueryFilteredMultivaluedProperti= es.java (rev 0) +++ jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatfor= m/services/jcr/impl/storage/jdbc/InspectionQueryFilteredMultivaluedProperti= es.java 2012-02-16 10:59:46 UTC (rev 5649) @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2012 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.exoplatform.services.jcr.impl.storage.jdbc; + +import org.exoplatform.services.jcr.impl.InspectionLog.InspectionStatus; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; + +/** + * @author Andrey Plotniko= v + * @version $Id: InspectionQueryFilteredMultivaluedProperties.java 34360 1= 6.02.2012 andrew.plotnikov $ + */ +class InspectionQueryFilteredMultivaluedProperties extends InspectionQuery +{ + + /** + * {@inheritDoc} + */ + public InspectionQueryFilteredMultivaluedProperties(String statement, S= tring[] fieldNames, String headerMessage, InspectionStatus status) + { + super(statement, fieldNames, headerMessage, status); + } + + /** + * {@inheritDoc} + */ + public PreparedStatement prepareStatement(Connection connection) throws= SQLException + { + PreparedStatement preparedStatement =3D super.prepareStatement(conne= ction); + preparedStatement.setBoolean(1, false); + + return preparedStatement; + } + +} Modified: jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exop= latform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainerChecker.ja= va =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatfor= m/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainerChecker.java 201= 2-02-16 07:31:26 UTC (rev 5648) +++ jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatfor= m/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainerChecker.java 201= 2-02-16 10:59:46 UTC (rev 5649) @@ -64,61 +64,6 @@ public static void checkDB(JDBCWorkspaceDataContainer jdbcDataContainer= , InspectionLog inspectionLog) throws RepositoryException, IOException { - - /** - * Data class, contains a combination of SQL states, description, fi= eld names and status = - */ - class InspectionQuery - { - /** - * SQL query that must be executed. - */ - private final String statement; - - /** - * Inspection query description. - */ - private final String description; - - /** - * Field names that must be showed in inspection log if something= wrong. - */ - private final String[] fieldNames; - - /** - * Corruption status. Is it critical - ERR, or not - WA= RN. - */ - private final InspectionStatus status; - - public InspectionQuery(String statement, String[] fieldNames, Str= ing headerMessage, InspectionStatus status) - { - this.statement =3D statement; - this.description =3D headerMessage; - this.fieldNames =3D fieldNames; - this.status =3D status; - } - - public String getStatement() - { - return statement; - } - - public String getDescription() - { - return description; - } - - public String[] getFieldNames() - { - return fieldNames; - } - - public InspectionStatus getStatus() - { - return status; - } - } - Set queries =3D new HashSet(); = // preload queries @@ -138,23 +83,26 @@ new String[]{DBConstants.COLUMN_ID, DBConstants.COLUMN_PARENTID, = DBConstants.COLUMN_NAME}, "Nodes that do not have at least one property", InspectionStatus.= ERR)); = - queries.add(new InspectionQuery(jdbcDataContainer.multiDb - ? "select * from JCR_MVALUE V where NOT EXISTS(select * from JCR_= MITEM P " - + "where V.PROPERTY_ID =3D P.ID and P.I_CLASS=3D2)" - : "select V.* from JCR_SVALUE V, JCR_SITEM I where V.PROPERTY_ID = =3D I.ID and I.CONTAINER_NAME=3D'" - + jdbcDataContainer.containerName + "' and NOT EXISTS(select *= from JCR_SITEM P where P.CONTAINER_NAME=3D'" - + jdbcDataContainer.containerName + "' and V.PROPERTY_ID =3D P= .ID and P.I_CLASS=3D2)", new String[]{ - DBConstants.COLUMN_ID, DBConstants.COLUMN_VPROPERTY_ID}, - "All value records that has not owner-property record", Inspectio= nStatus.ERR)); + queries + .add(new InspectionQuery(jdbcDataContainer.multiDb + ? "select * from JCR_MVALUE V where NOT EXISTS(select * from J= CR_MITEM P " + + "where V.PROPERTY_ID =3D P.ID and P.I_CLASS=3D2)" + : "select * from JCR_SVALUE V where NOT EXISTS(select * from J= CR_SITEM P " + + "where V.PROPERTY_ID =3D P.ID and P.I_CLASS=3D2)", new St= ring[]{DBConstants.COLUMN_ID, + DBConstants.COLUMN_VPROPERTY_ID}, "All value records that has = not owner-property record", + InspectionStatus.ERR)); + + queries + .add(new InspectionQueryFilteredMultivaluedProperties( + jdbcDataContainer.multiDb + ? "select * from JCR_MITEM P where P.I_CLASS=3D2 and P.P_MU= LTIVALUED=3D? and NOT EXISTS( select * from JCR_MVALUE V " + + "where V.PROPERTY_ID=3DP.ID)" + : "select * from JCR_SITEM P where P.CONTAINER_NAME=3D'" + + jdbcDataContainer.containerName + + "' and P.I_CLASS=3D2 and P.P_MULTIVALUED=3D? and NOT E= XISTS( select * from JCR_SVALUE V where V.PROPERTY_ID=3DP.ID)", + new String[]{DBConstants.COLUMN_ID, DBConstants.COLUMN_PARENTI= D, DBConstants.COLUMN_NAME}, + "All properties that have not value record.", InspectionStatus= .ERR)); = - queries.add(new InspectionQuery(jdbcDataContainer.multiDb - ? "select * from JCR_MITEM P where P.I_CLASS=3D2 and NOT EXISTS( = select * from JCR_MVALUE V " - + "where V.PROPERTY_ID=3DP.ID)" : "select * from JCR_SITEM P w= here P.CONTAINER_NAME=3D'" - + jdbcDataContainer.containerName - + "' and P.I_CLASS=3D2 and NOT EXISTS( select * from JCR_SVALU= E V where V.PROPERTY_ID=3DP.ID)", new String[]{ - DBConstants.COLUMN_ID, DBConstants.COLUMN_PARENTID, DBConstants.C= OLUMN_NAME}, - "All properties that have not value record.", InspectionStatus.ER= R)); - = // The differences in the queries by DB dialect. // Oracle doesn't work correct with default query because empty valu= e stored as null value. String statement; @@ -187,24 +135,17 @@ } queries.add(new InspectionQuery(statement, new String[]{DBConstants.= COLUMN_ID}, "Incorrect JCR_VALUE records", InspectionStatus.ERR)); - = - queries.add(new InspectionQuery(jdbcDataContainer.multiDb - ? "select * from JCR_MITEM P where P.P_TYPE=3D9 and NOT EXISTS " - + "(select * from JCR_MREF R where P.ID=3DR.PROPERTY_ID)" - : "select * from JCR_SITEM P where P.CONTAINER_NAME=3D'" + jdbcDa= taContainer.containerName - + "' and P.P_TYPE=3D9 and NOT EXISTS( select * from JCR_SREF R= where P.ID=3DR.PROPERTY_ID)", new String[]{ - DBConstants.COLUMN_ID, DBConstants.COLUMN_PARENTID, DBConstants.C= OLUMN_NAME}, - "Reference properties without reference records", InspectionStatu= s.ERR)); = - // properties can refer to missing node. It is possible to perform t= his usecase via JCR API with no exceptions = - queries.add(new InspectionQuery(jdbcDataContainer.multiDb - ? "select * from JCR_MREF R where NOT EXISTS(select * from JCR_MI= TEM N where R.NODE_ID=3DN.ID)" - : "select * from JCR_SREF R, JCR_SITEM I where R.PROPERTY_ID =3D = I.ID and I.CONTAINER_NAME=3D'" - + jdbcDataContainer.containerName - + "' and NOT EXISTS(select * from JCR_SITEM N where N.CONTAIN= ER_NAME=3D'" - + jdbcDataContainer.containerName + "' and R.NODE_ID=3DN.ID)",= new String[]{"NODE_ID", "PROPERTY_ID", - DBConstants.COLUMN_VORDERNUM}, - "Reference records that linked to unexisted nodes. Can be normal = for some usecases.", InspectionStatus.WARN)); + queries + .add(new InspectionQueryFilteredMultivaluedProperties( + jdbcDataContainer.multiDb + ? "select * from JCR_MITEM P where P.P_TYPE=3D9 and P.P_MUL= TIVALUED=3D? and NOT EXISTS " + + "(select * from JCR_MREF R where P.ID=3DR.PROPERTY_ID)" + : "select * from JCR_SITEM P where P.CONTAINER_NAME=3D'" + + jdbcDataContainer.containerName + + "' and P.P_TYPE=3D9 and P.P_MULTIVALUED=3D? and NOT EX= ISTS( select * from JCR_SREF R where P.ID=3DR.PROPERTY_ID)", + new String[]{DBConstants.COLUMN_ID, DBConstants.COLUMN_PARENTI= D, DBConstants.COLUMN_NAME}, + "Reference properties without reference records", InspectionSt= atus.ERR)); = // an item is its own parent. = queries.add(new InspectionQuery(jdbcDataContainer.multiDb @@ -241,7 +182,8 @@ ResultSet resultSet =3D null; try { - st =3D jdbcConn.prepareStatement(query.getStatement()); + st =3D query.prepareStatement(jdbcConn); + // the result of query is expected to be empty = resultSet =3D st.executeQuery(); if (resultSet.next()) Modified: jcr/branches/1.15.x/exo.jcr.component.core/src/test/java/org/exop= latform/services/jcr/impl/TestRepositoryCheckController.java =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- jcr/branches/1.15.x/exo.jcr.component.core/src/test/java/org/exoplatfor= m/services/jcr/impl/TestRepositoryCheckController.java 2012-02-16 07:31:26 = UTC (rev 5648) +++ jcr/branches/1.15.x/exo.jcr.component.core/src/test/java/org/exoplatfor= m/services/jcr/impl/TestRepositoryCheckController.java 2012-02-16 10:59:46 = UTC (rev 5649) @@ -570,64 +570,11 @@ } = /** - * Usecase: Reference records that linked to unexisted nodes. Can be no= rmal for some usecases. - */ - public void testDBUsecasesRefPropertiesLinksToUnexistedNodesSingleDB() = throws Exception - { - checkDBUsecasesRefPropertiesLinksToUnexistedNodes(helper.createRepos= itory(container, false, false)); - } - - /** - * Usecase: Reference records that linked to unexisted nodes. Can be no= rmal for some usecases. - */ - public void testDBUsecasesRefPropertiesLinksToUnexistedNodesMultiDB() t= hrows Exception - { - checkDBUsecasesRefPropertiesLinksToUnexistedNodes(helper.createRepos= itory(container, true, false)); - } - - private void checkDBUsecasesRefPropertiesLinksToUnexistedNodes(Manageab= leRepository repository) throws Exception - { - // create repository and add property - SessionImpl session =3D - (SessionImpl)repository.login(credentials, repository.getConfigur= ation().getSystemWorkspaceName()); - NodeImpl refNode =3D (NodeImpl)session.getRootNode().addNode("refNod= e"); - refNode.addMixin("mix:referenceable"); - NodeImpl node =3D (NodeImpl)session.getRootNode().addNode("testNode"= ); - PropertyImpl prop =3D (PropertyImpl)node.setProperty("refProp", refN= ode); - session.save(); - session.logout(); - - // repository is consistent - checkController =3D new RepositoryCheckController(repository); - assertTrue(checkController.checkRepositoryDataBaseConsistency().star= tsWith("Repository data is consistent")); - checkController.getLastLogFile().delete(); - - WorkspaceEntry wsEntry =3D repository.getConfiguration().getWorkspac= eEntries().get(0); - boolean isMultiDb =3D wsEntry.getContainer().getParameterBoolean(JDB= CWorkspaceDataContainer.MULTIDB); - - // change node id in REF table - String sourceName =3D wsEntry.getContainer().getParameterValue(JDBCW= orkspaceDataContainer.SOURCE_NAME); - - Connection conn =3D ((DataSource)new InitialContext().lookup(sourceN= ame)).getConnection(); - conn.prepareStatement( - "UPDATE JCR_" + (isMultiDb ? "M" : "S") + "REF SET NODE_ID =3D 'u= nexisted-id' WHERE PROPERTY_ID =3D '" - + (isMultiDb ? "" : wsEntry.getName()) + prop.getInternalIdent= ifier() + "'").execute(); - - conn.commit(); - conn.close(); - - // repository is inconsistent - assertTrue(checkController.checkRepositoryDataBaseConsistency().star= tsWith( - "Repository data is consistent, except some warnings")); - checkController.getLastLogFile().delete(); - } - - /** * Usecase: value records has no item record. */ public void testDBUsecasesValueRecordHasNoItemRecordSingleDB() throws E= xception { - checkDBUsecasesPropertiesHasNoValueRecord(helper.createRepository(co= ntainer, false, false)); + checkDBUsecasesValueRecordHasNoItemRecord(helper.createRepository(co= ntainer, false, false)); } = /** @@ -679,7 +626,8 @@ */ public void testDBUsecasesPropertiesHasNoValueRecordSingleDB() throws E= xception { - checkDBUsecasesPropertiesHasNoValueRecord(helper.createRepository(co= ntainer, false, false)); + checkDBUsecasesPropertiesHasNoSingleValueRecord(helper.createReposit= ory(container, false, false)); + checkDBUsecasesPropertiesHasEmptyMultiValueRecord(helper.createRepos= itory(container, false, false)); } = /** @@ -687,10 +635,11 @@ */ public void testDBUsecasesPropertiesHasNoValueRecordMultiDB() throws Ex= ception { - checkDBUsecasesPropertiesHasNoValueRecord(helper.createRepository(co= ntainer, true, false)); + checkDBUsecasesPropertiesHasNoSingleValueRecord(helper.createReposit= ory(container, true, false)); + checkDBUsecasesPropertiesHasEmptyMultiValueRecord(helper.createRepos= itory(container, false, false)); } = - private void checkDBUsecasesPropertiesHasNoValueRecord(ManageableReposi= tory repository) throws Exception + private void checkDBUsecasesPropertiesHasNoSingleValueRecord(Manageable= Repository repository) throws Exception { // create repository and add property SessionImpl session =3D @@ -723,6 +672,21 @@ checkController.getLastLogFile().delete(); } = + private void checkDBUsecasesPropertiesHasEmptyMultiValueRecord(Manageab= leRepository repository) throws Exception + { + // create repository and add property + SessionImpl session =3D + (SessionImpl)repository.login(credentials, repository.getConfigur= ation().getSystemWorkspaceName()); + PropertyImpl prop =3D (PropertyImpl)session.getRootNode().addNode("t= estNode").setProperty("prop", new String[]{}); + session.save(); + session.logout(); + + // repository is consistent + checkController =3D new RepositoryCheckController(repository); + assertTrue(checkController.checkRepositoryDataBaseConsistency().star= tsWith("Repository data is consistent")); + checkController.getLastLogFile().delete(); + } + /** * Usecase: reference properties without reference records. */ --===============3201311250005725456==--