[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.

do-not-reply at jboss.org do-not-reply at jboss.org
Thu Feb 16 05:59:47 EST 2012


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/InspectionQueryFilteredMultivaluedProperties.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/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/InspectionQuery.java	                        (rev 0)
+++ jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/InspectionQuery.java	2012-02-16 10:59:46 UTC (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 <a href="mailto:aplotnikov at exoplatform.com">Andrey Plotnikov</a>
+ * @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 - <b>ERR</b>, or not - <b>WARN</b>.
+    */
+   public InspectionStatus status;
+
+   public InspectionQuery(String statement, String[] fieldNames, String headerMessage, InspectionStatus status)
+   {
+      this.statement = statement;
+      this.description = headerMessage;
+      this.fieldNames = fieldNames;
+      this.status = 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 statements to the database. 
+    * 
+    * @param connection
+    *          connection to workspace storage
+    * @return
+    *          a new default PreparedStatement object containing the pre-compiled 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/exoplatform/services/jcr/impl/storage/jdbc/InspectionQueryFilteredMultivaluedProperties.java
===================================================================
--- jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/InspectionQueryFilteredMultivaluedProperties.java	                        (rev 0)
+++ jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/InspectionQueryFilteredMultivaluedProperties.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 <a href="mailto:aplotnikov at exoplatform.com">Andrey Plotnikov</a>
+ * @version $Id: InspectionQueryFilteredMultivaluedProperties.java 34360 16.02.2012 andrew.plotnikov $
+ */
+class InspectionQueryFilteredMultivaluedProperties extends InspectionQuery
+{
+
+   /**
+    * {@inheritDoc}
+    */
+   public InspectionQueryFilteredMultivaluedProperties(String statement, String[] fieldNames, String headerMessage, InspectionStatus status)
+   {
+      super(statement, fieldNames, headerMessage, status);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public PreparedStatement prepareStatement(Connection connection) throws SQLException
+   {
+      PreparedStatement preparedStatement = super.prepareStatement(connection);
+      preparedStatement.setBoolean(1, false);
+
+      return preparedStatement;
+   }
+
+}

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/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainerChecker.java	2012-02-16 07:31:26 UTC (rev 5648)
+++ jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainerChecker.java	2012-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, field 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 - <b>ERR</b>, or not - <b>WARN</b>.
-          */
-         private final InspectionStatus status;
-
-         public InspectionQuery(String statement, String[] fieldNames, String headerMessage, InspectionStatus status)
-         {
-            this.statement = statement;
-            this.description = headerMessage;
-            this.fieldNames = fieldNames;
-            this.status = status;
-         }
-
-         public String getStatement()
-         {
-            return statement;
-         }
-
-         public String getDescription()
-         {
-            return description;
-         }
-
-         public String[] getFieldNames()
-         {
-            return fieldNames;
-         }
-
-         public InspectionStatus getStatus()
-         {
-            return status;
-         }
-      }
-
       Set<InspectionQuery> queries = new HashSet<InspectionQuery>();
 
       // 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 = P.ID and P.I_CLASS=2)"
-         : "select V.* from JCR_SVALUE V, JCR_SITEM I where V.PROPERTY_ID = I.ID and I.CONTAINER_NAME='"
-            + jdbcDataContainer.containerName + "' and NOT EXISTS(select * from JCR_SITEM P where P.CONTAINER_NAME='"
-            + jdbcDataContainer.containerName + "' and V.PROPERTY_ID = P.ID and P.I_CLASS=2)", new String[]{
-         DBConstants.COLUMN_ID, DBConstants.COLUMN_VPROPERTY_ID},
-         "All value records that has not owner-property record", 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 = P.ID and P.I_CLASS=2)"
+            : "select * from JCR_SVALUE V where NOT EXISTS(select * from JCR_SITEM P "
+               + "where V.PROPERTY_ID = P.ID and P.I_CLASS=2)", new String[]{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=2 and P.P_MULTIVALUED=? and NOT EXISTS( select * from JCR_MVALUE V "
+                  + "where V.PROPERTY_ID=P.ID)"
+               : "select * from JCR_SITEM P where P.CONTAINER_NAME='"
+                  + jdbcDataContainer.containerName
+                  + "' and P.I_CLASS=2 and P.P_MULTIVALUED=? and NOT EXISTS( select * from JCR_SVALUE V where V.PROPERTY_ID=P.ID)",
+            new String[]{DBConstants.COLUMN_ID, DBConstants.COLUMN_PARENTID, 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=2 and NOT EXISTS( select * from JCR_MVALUE V "
-            + "where V.PROPERTY_ID=P.ID)" : "select * from JCR_SITEM P where P.CONTAINER_NAME='"
-            + jdbcDataContainer.containerName
-            + "' and P.I_CLASS=2 and NOT EXISTS( select * from JCR_SVALUE V where V.PROPERTY_ID=P.ID)", new String[]{
-         DBConstants.COLUMN_ID, DBConstants.COLUMN_PARENTID, DBConstants.COLUMN_NAME},
-         "All properties that have not value record.", InspectionStatus.ERR));
-      
       // The differences in the queries by DB dialect.
       // Oracle doesn't work correct with default query because empty value 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=9 and NOT EXISTS "
-            + "(select * from JCR_MREF R where P.ID=R.PROPERTY_ID)"
-         : "select * from JCR_SITEM P where P.CONTAINER_NAME='" + jdbcDataContainer.containerName
-            + "' and P.P_TYPE=9 and NOT EXISTS( select * from JCR_SREF R where P.ID=R.PROPERTY_ID)", new String[]{
-         DBConstants.COLUMN_ID, DBConstants.COLUMN_PARENTID, DBConstants.COLUMN_NAME},
-         "Reference properties without reference records", InspectionStatus.ERR));
 
-      // properties can refer to missing node. It is possible to perform this usecase via JCR API with no exceptions 
-      queries.add(new InspectionQuery(jdbcDataContainer.multiDb
-         ? "select * from JCR_MREF R where NOT EXISTS(select * from JCR_MITEM N where R.NODE_ID=N.ID)"
-         : "select * from JCR_SREF R, JCR_SITEM I where R.PROPERTY_ID = I.ID and I.CONTAINER_NAME='"
-            + jdbcDataContainer.containerName
-            + "'  and NOT EXISTS(select * from JCR_SITEM N where N.CONTAINER_NAME='"
-            + jdbcDataContainer.containerName + "' and R.NODE_ID=N.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=9 and P.P_MULTIVALUED=? and NOT EXISTS "
+                  + "(select * from JCR_MREF R where P.ID=R.PROPERTY_ID)"
+               : "select * from JCR_SITEM P where P.CONTAINER_NAME='"
+                  + jdbcDataContainer.containerName
+                  + "' and P.P_TYPE=9 and P.P_MULTIVALUED=? and NOT EXISTS( select * from JCR_SREF R where P.ID=R.PROPERTY_ID)",
+            new String[]{DBConstants.COLUMN_ID, DBConstants.COLUMN_PARENTID, DBConstants.COLUMN_NAME},
+            "Reference properties without reference records", InspectionStatus.ERR));
 
       // an item is its own parent. 
       queries.add(new InspectionQuery(jdbcDataContainer.multiDb
@@ -241,7 +182,8 @@
             ResultSet resultSet = null;
             try
             {
-               st = jdbcConn.prepareStatement(query.getStatement());
+               st = query.prepareStatement(jdbcConn);
+
                // the result of query is expected to be empty 
                resultSet = st.executeQuery();
                if (resultSet.next())

Modified: jcr/branches/1.15.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/TestRepositoryCheckController.java
===================================================================
--- jcr/branches/1.15.x/exo.jcr.component.core/src/test/java/org/exoplatform/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/exoplatform/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 normal for some usecases.
-    */
-   public void testDBUsecasesRefPropertiesLinksToUnexistedNodesSingleDB() throws Exception
-   {
-      checkDBUsecasesRefPropertiesLinksToUnexistedNodes(helper.createRepository(container, false, false));
-   }
-
-   /**
-    * Usecase: Reference records that linked to unexisted nodes. Can be normal for some usecases.
-    */
-   public void testDBUsecasesRefPropertiesLinksToUnexistedNodesMultiDB() throws Exception
-   {
-      checkDBUsecasesRefPropertiesLinksToUnexistedNodes(helper.createRepository(container, true, false));
-   }
-
-   private void checkDBUsecasesRefPropertiesLinksToUnexistedNodes(ManageableRepository repository) throws Exception
-   {
-      // create repository and add property
-      SessionImpl session =
-         (SessionImpl)repository.login(credentials, repository.getConfiguration().getSystemWorkspaceName());
-      NodeImpl refNode = (NodeImpl)session.getRootNode().addNode("refNode");
-      refNode.addMixin("mix:referenceable");
-      NodeImpl node = (NodeImpl)session.getRootNode().addNode("testNode");
-      PropertyImpl prop = (PropertyImpl)node.setProperty("refProp", refNode);
-      session.save();
-      session.logout();
-
-      // repository is consistent
-      checkController = new RepositoryCheckController(repository);
-      assertTrue(checkController.checkRepositoryDataBaseConsistency().startsWith("Repository data is consistent"));
-      checkController.getLastLogFile().delete();
-
-      WorkspaceEntry wsEntry = repository.getConfiguration().getWorkspaceEntries().get(0);
-      boolean isMultiDb = wsEntry.getContainer().getParameterBoolean(JDBCWorkspaceDataContainer.MULTIDB);
-
-      // change node id in REF table
-      String sourceName = wsEntry.getContainer().getParameterValue(JDBCWorkspaceDataContainer.SOURCE_NAME);
-
-      Connection conn = ((DataSource)new InitialContext().lookup(sourceName)).getConnection();
-      conn.prepareStatement(
-         "UPDATE JCR_" + (isMultiDb ? "M" : "S") + "REF SET NODE_ID = 'unexisted-id' WHERE PROPERTY_ID = '"
-            + (isMultiDb ? "" : wsEntry.getName()) + prop.getInternalIdentifier() + "'").execute();
-
-      conn.commit();
-      conn.close();
-
-      // repository is inconsistent
-      assertTrue(checkController.checkRepositoryDataBaseConsistency().startsWith(
-         "Repository data is consistent, except some warnings"));
-      checkController.getLastLogFile().delete();
-   }
-
-   /**
     * Usecase: value records has no item record.
     */
    public void testDBUsecasesValueRecordHasNoItemRecordSingleDB() throws Exception
    {
-      checkDBUsecasesPropertiesHasNoValueRecord(helper.createRepository(container, false, false));
+      checkDBUsecasesValueRecordHasNoItemRecord(helper.createRepository(container, false, false));
    }
 
    /**
@@ -679,7 +626,8 @@
     */
    public void testDBUsecasesPropertiesHasNoValueRecordSingleDB() throws Exception
    {
-      checkDBUsecasesPropertiesHasNoValueRecord(helper.createRepository(container, false, false));
+      checkDBUsecasesPropertiesHasNoSingleValueRecord(helper.createRepository(container, false, false));
+      checkDBUsecasesPropertiesHasEmptyMultiValueRecord(helper.createRepository(container, false, false));
    }
 
    /**
@@ -687,10 +635,11 @@
     */
    public void testDBUsecasesPropertiesHasNoValueRecordMultiDB() throws Exception
    {
-      checkDBUsecasesPropertiesHasNoValueRecord(helper.createRepository(container, true, false));
+      checkDBUsecasesPropertiesHasNoSingleValueRecord(helper.createRepository(container, true, false));
+      checkDBUsecasesPropertiesHasEmptyMultiValueRecord(helper.createRepository(container, false, false));
    }
 
-   private void checkDBUsecasesPropertiesHasNoValueRecord(ManageableRepository repository) throws Exception
+   private void checkDBUsecasesPropertiesHasNoSingleValueRecord(ManageableRepository repository) throws Exception
    {
       // create repository and add property
       SessionImpl session =
@@ -723,6 +672,21 @@
       checkController.getLastLogFile().delete();
    }
 
+   private void checkDBUsecasesPropertiesHasEmptyMultiValueRecord(ManageableRepository repository) throws Exception
+   {
+      // create repository and add property
+      SessionImpl session =
+         (SessionImpl)repository.login(credentials, repository.getConfiguration().getSystemWorkspaceName());
+      PropertyImpl prop = (PropertyImpl)session.getRootNode().addNode("testNode").setProperty("prop", new String[]{});
+      session.save();
+      session.logout();
+
+      // repository is consistent
+      checkController = new RepositoryCheckController(repository);
+      assertTrue(checkController.checkRepositoryDataBaseConsistency().startsWith("Repository data is consistent"));
+      checkController.getLastLogFile().delete();
+   }
+
    /**
     * Usecase: reference properties without reference records.
     */



More information about the exo-jcr-commits mailing list