← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 2424: Applied path from Tran on patient datavalue archive. Nice work.

 

------------------------------------------------------------
revno: 2424
committer: Lars Helge Overland <larshelge@xxxxxxxxx>
branch nick: dhis2
timestamp: Sun 2010-10-24 17:41:13 +0200
message:
  Applied path from Tran on patient datavalue archive. Nice work.
modified:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataarchive/DataArchiveService.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataarchive/DataArchiveStore.java
  dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/dataarchive/DefaultDataArchiveService.java
  dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/dataarchive/jdbc/JdbcDataArchiveStore.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/startup/TableCreator.java
  dhis-2/dhis-services/dhis-service-options/src/main/resources/help_content.xml
  dhis-2/dhis-services/dhis-service-patient/src/main/resources/org/hisp/dhis/patientdatavalue/hibernate/PatientDataValue.hbm.xml
  dhis-2/dhis-support/dhis-support-jdbc/src/main/java/org/hisp/dhis/jdbc/StatementBuilder.java
  dhis-2/dhis-support/dhis-support-jdbc/src/main/java/org/hisp/dhis/jdbc/statementbuilder/DerbyStatementBuilder.java
  dhis-2/dhis-support/dhis-support-jdbc/src/main/java/org/hisp/dhis/jdbc/statementbuilder/H2StatementBuilder.java
  dhis-2/dhis-support/dhis-support-jdbc/src/main/java/org/hisp/dhis/jdbc/statementbuilder/MySQLStatementBuilder.java
  dhis-2/dhis-support/dhis-support-jdbc/src/main/java/org/hisp/dhis/jdbc/statementbuilder/PostgreSQLStatementBuilder.java
  dhis-2/dhis-web/dhis-web-caseentry/src/main/java/org/hisp/dhis/caseentry/action/caseentry/CompleteDataEntryAction.java
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/resources/META-INF/dhis/beans.xml
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/resources/org/hisp/dhis/dataadmin/i18n_module.properties
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/resources/struts.xml
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/webapp/dhis-web-maintenance-dataadmin/index.vm
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/webapp/dhis-web-maintenance-dataadmin/javascript/dataArchive.js
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/webapp/dhis-web-maintenance-dataadmin/menu.vm


--
lp:dhis2
https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk

Your team DHIS 2 developers is subscribed to branch lp:dhis2.
To unsubscribe from this branch go to https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk/+edit-subscription
=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataarchive/DataArchiveService.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataarchive/DataArchiveService.java	2010-10-01 09:05:32 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataarchive/DataArchiveService.java	2010-10-24 15:41:13 +0000
@@ -39,4 +39,8 @@
     int archiveData( Date startDate, Date endDate, DataArchiveOperation operation, DataEliminationStrategy strategy );
 
     int getNumberOfOverlappingValues();
+    
+    int archivePatientData( Date startDate, Date endDate, DataArchiveOperation operation, DataEliminationStrategy strategy );
+    
+    int getNumberOfOverlappingPatientValues();
 }

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataarchive/DataArchiveStore.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataarchive/DataArchiveStore.java	2010-04-12 21:23:33 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataarchive/DataArchiveStore.java	2010-10-24 15:41:13 +0000
@@ -35,16 +35,35 @@
 public interface DataArchiveStore
 {
     void archiveData( Date startDate, Date endDate );
-    
+
     void unArchiveData( Date startDate, Date endDate );
-    
+
     int getNumberOfOverlappingValues();
-    
+
     int getNumberOfArchivedValues();
-    
+
     void deleteRegularOverlappingData();
-    
+
     void deleteArchivedOverlappingData();
-    
+
     void deleteOldestOverlappingData();
+
+    // -------------------------------------------------------------------------
+    // Archive for patient data value
+    // -------------------------------------------------------------------------
+
+    void archivePatientData( Date startDate, Date endDate );
+
+    void unArchivePatientData( Date startDate, Date endDate );
+    
+    int getNumberOfOverlappingPatientValues();
+
+    int getNumberOfArchivedPatientValues();
+
+    void deleteRegularOverlappingPatientData();
+
+    void deleteArchivedOverlappingPatientData();
+
+    void deleteOldestOverlappingPatientData();
+    
 }

=== modified file 'dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/dataarchive/DefaultDataArchiveService.java'
--- dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/dataarchive/DefaultDataArchiveService.java	2010-10-01 09:05:32 +0000
+++ dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/dataarchive/DefaultDataArchiveService.java	2010-10-24 15:41:13 +0000
@@ -92,4 +92,46 @@
     {
         return dataArchiveStore.getNumberOfOverlappingValues();
     }
+    
+    @Transactional
+    public int archivePatientData( Date startDate, Date endDate, DataArchiveOperation operation, DataEliminationStrategy strategy )
+    {
+        // ---------------------------------------------------------------------
+        // Eliminate duplicate data
+        // ---------------------------------------------------------------------
+
+        if ( DataEliminationStrategy.ARCHIVE.equals( strategy ) )
+        {
+            dataArchiveStore.deleteArchivedOverlappingPatientData();
+        }
+        else if ( DataEliminationStrategy.REGULAR.equals( strategy ) )
+        {
+            dataArchiveStore.deleteRegularOverlappingPatientData();
+        }
+        else // OLDEST
+        {
+            dataArchiveStore.deleteOldestOverlappingPatientData();
+        }
+        
+        // ---------------------------------------------------------------------
+        // Archive data
+        // ---------------------------------------------------------------------
+
+        if ( DataArchiveOperation.ARCHIVE.equals( operation ) )
+        {
+            dataArchiveStore.archivePatientData( startDate, endDate );
+        }
+        else // UNARCHIVE
+        {
+            dataArchiveStore.unArchivePatientData( startDate, endDate );
+        }
+
+        return dataArchiveStore.getNumberOfArchivedPatientValues();
+    }
+
+    public int getNumberOfOverlappingPatientValues()
+    {
+        return dataArchiveStore.getNumberOfOverlappingPatientValues();
+    }
+    
 }

=== modified file 'dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/dataarchive/jdbc/JdbcDataArchiveStore.java'
--- dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/dataarchive/jdbc/JdbcDataArchiveStore.java	2010-10-04 08:56:54 +0000
+++ dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/dataarchive/jdbc/JdbcDataArchiveStore.java	2010-10-24 15:41:13 +0000
@@ -57,22 +57,20 @@
     private StatementBuilder statementBuilder;
 
     // -------------------------------------------------------------------------
-    // Dependencies
+    // Implementation methods for Data values
     // -------------------------------------------------------------------------
 
     public void archiveData( Date startDate, Date endDate )
     {
         // Move data from datavalue to datavaluearchive
-        
-        String sql = "INSERT INTO datavaluearchive ( " 
-            + "SELECT d.* FROM datavalue AS d "
-            + "JOIN period AS p ON d.periodid=p.periodid " 
-            + "WHERE p.startdate>='" + getMediumDateString( startDate ) + "' " 
-            + "AND p.enddate<='" + getMediumDateString( endDate ) + "' );";
+
+        String sql = "INSERT INTO datavaluearchive ( " + "SELECT d.* FROM datavalue AS d "
+            + "JOIN period AS p ON d.periodid=p.periodid " + "WHERE p.startdate>='" + getMediumDateString( startDate ) + "' " + 
+            "AND p.enddate<='" + getMediumDateString( endDate ) + "' );";
 
         log.info( sql );
         jdbcTemplate.execute( sql );
-        
+
         // Delete data from datavalue
 
         sql = statementBuilder.archiveData( getMediumDateString( startDate ), getMediumDateString( endDate ) );
@@ -85,11 +83,9 @@
     {
         // Move data from datavalue to datavaluearchive
 
-        String sql = "INSERT INTO datavalue ( " 
-            + "SELECT a.* FROM datavaluearchive AS a "
-            + "JOIN period AS p ON a.periodid=p.periodid " 
-            + "WHERE p.startdate>='" + getMediumDateString( startDate )+ "' " 
-            + "AND p.enddate<='" + getMediumDateString( endDate ) + "' );";
+        String sql = "INSERT INTO datavalue ( " + "SELECT a.* FROM datavaluearchive AS a "
+            + "JOIN period AS p ON a.periodid=p.periodid " + "WHERE p.startdate>='" + getMediumDateString( startDate ) + "' " + 
+            "AND p.enddate<='" + getMediumDateString( endDate ) + "' );";
 
         log.info( sql );
         jdbcTemplate.execute( sql );
@@ -105,13 +101,11 @@
     public int getNumberOfOverlappingValues()
     {
         String sql = "SELECT COUNT(*) FROM datavaluearchive AS a "
-            + "JOIN datavalue AS d ON a.dataelementid=d.dataelementid " 
-            + "AND a.periodid=d.periodid "
-            + "AND a.sourceid=d.sourceid " 
-            + "AND a.categoryoptioncomboid=d.categoryoptioncomboid;";
+            + "JOIN datavalue AS d ON a.dataelementid=d.dataelementid " + "AND a.periodid=d.periodid "
+            + "AND a.sourceid=d.sourceid " + "AND a.categoryoptioncomboid=d.categoryoptioncomboid;";
 
         log.info( sql );
-        
+
         return jdbcTemplate.queryForInt( sql );
     }
 
@@ -120,7 +114,7 @@
         String sql = "SELECT COUNT(*) as dem FROM datavaluearchive;";
 
         log.info( sql );
-        return jdbcTemplate.queryForInt( sql );   
+        return jdbcTemplate.queryForInt( sql );
     }
 
     public void deleteRegularOverlappingData()
@@ -155,4 +149,108 @@
         log.info( sql );
         jdbcTemplate.execute( sql );
     }
+    
+    // -------------------------------------------------------------------------
+    // Implementation methods for Patient data values
+    // -------------------------------------------------------------------------
+
+    public void archivePatientData( Date startDate, Date endDate )
+    {
+        // Move data from patientdatavalue to patientdatavaluearchive
+        
+        String sql ="INSERT INTO patientdatavaluearchive ( " + "SELECT pdv.* FROM patientdatavalue AS pdv "
+            + "INNER JOIN programstageinstance AS psi "
+            +    "ON pdv.programstageinstanceid = psi.programstageinstanceid "
+            + "INNER JOIN programinstance AS pi "
+            +    "ON pi.programinstanceid = psi.programinstanceid "
+            + "WHERE pi.enddate >= '" + getMediumDateString( startDate ) + "' "
+            +    "AND pi.enddate <= '" + getMediumDateString( endDate ) + "' );";
+        
+        log.info( sql );
+        jdbcTemplate.execute( sql );
+
+        // Delete data from patientdatavalue
+
+        sql = statementBuilder.archivePatientData( getMediumDateString( startDate ), getMediumDateString( endDate ) );
+
+        log.info( sql );
+        jdbcTemplate.execute( sql );
+    }
+
+    public void unArchivePatientData( Date startDate, Date endDate )
+    {
+        // Move data from patientdatavalue to patientdatavaluearchive
+
+        String sql ="INSERT INTO patientdatavalue ( " + "SELECT * FROM patientdatavaluearchive AS pdv "
+        + "INNER JOIN programstageinstance AS psi "
+        +    "ON pdv.programstageinstanceid = psi.programstageinstanceid "
+        + "INNER JOIN programinstance AS pi "
+        +    "ON pi.programinstanceid = psi.programinstanceid "
+        + "WHERE pi.enddate >= '" + getMediumDateString( startDate ) + "' "
+        +    "AND pi.enddate <= '" + getMediumDateString( endDate ) + "' );";
+
+        log.info( sql );
+        jdbcTemplate.execute( sql );
+
+        // Delete data from patientdatavalue
+
+        sql = statementBuilder.unArchivePatientData( getMediumDateString( startDate ), getMediumDateString( endDate ) );
+
+        log.info( sql );
+        jdbcTemplate.execute( sql );
+    }
+    
+    public int getNumberOfOverlappingPatientValues()
+    {
+        String sql =  "SELECT COUNT(*) FROM patientdatavaluearchive AS pdv "
+                + "INNER JOIN programstageinstance AS psi "
+                +    "ON pdv.programstageinstanceid = psi.programstageinstanceid "
+                + "INNER JOIN programinstance AS pi "
+                +    "ON pi.programinstanceid = psi.programinstanceid";
+        log.info( sql );
+
+        return jdbcTemplate.queryForInt( sql );
+    }
+
+    public int getNumberOfArchivedPatientValues()
+    {
+        String sql = "SELECT COUNT(*) as dem FROM patientdatavaluearchive;";
+
+        log.info( sql );
+        return jdbcTemplate.queryForInt( sql );
+    }
+
+    public void deleteRegularOverlappingPatientData()
+    {
+        String sql = statementBuilder.deleteRegularOverlappingPatientData();
+
+        log.info( sql );
+        jdbcTemplate.execute( sql );
+    }
+
+    public void deleteArchivedOverlappingPatientData()
+    {
+        String sql = statementBuilder.deleteArchivedOverlappingPatientData();
+
+        log.info( sql );
+        jdbcTemplate.execute( sql );
+    }
+
+    public void deleteOldestOverlappingPatientData()
+    {
+        // Delete overlaps from patientdatavalue which are older than patientdatavaluearchive
+
+        String sql = statementBuilder.deleteOldestOverlappingPatientDataValue();
+
+        log.info( sql );
+        jdbcTemplate.execute( sql );
+
+        // Delete overlaps from patientdatavaluearchive which are older than patientdatavalue
+
+        sql = statementBuilder.deleteOldestOverlappingPatientArchiveData();
+
+        log.info( sql );
+        jdbcTemplate.execute( sql );
+    }
+
 }

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/startup/TableCreator.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/startup/TableCreator.java	2010-05-12 16:27:25 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/startup/TableCreator.java	2010-10-24 15:41:13 +0000
@@ -160,5 +160,34 @@
         {
             log.info( "Table datavaluearchive exists" );
         }
+        
+        // -----------------------------------------------------------------
+        // ArchivedPatientDataValue
+        // -----------------------------------------------------------------
+
+        try
+        {
+            final String sql = 
+                "CREATE TABLE patientdatavaluearchive ( " +
+                 " programstageinstanceid integer NOT NULL, " +
+                 " dataelementid integer NOT NULL, " +
+                 " organisationunitid integer NOT NULL, " +
+                 " categoryoptioncomboid integer default NULL, " +
+                 " value varchar(255) default NULL, " +
+                 " providedbyanotherfacility boolean NOT NULL, " +
+                 " timestamp TIMESTAMP, " +
+                 " PRIMARY KEY  (programstageinstanceid,dataelementid,organisationunitid), " +
+                 " CONSTRAINT fk_patientdatavaluearchive_organisationunitid FOREIGN KEY (organisationunitid) REFERENCES organisationunit (organisationunitid), " +
+                 " CONSTRAINT fk_patientdatavaluearchive_programstageinstanceid FOREIGN KEY (programstageinstanceid) REFERENCES programstageinstance (programstageinstanceid) " +
+                 "        );";
+                            
+            jdbcTemplate.execute( sql );
+            
+            log.info( "Created table patientdatavaluearchive" );
+        }
+        catch ( Exception ex )
+        {
+            log.info( "Table patientdatavaluearchive exists" );
+        }
     }
 }

=== modified file 'dhis-2/dhis-services/dhis-service-options/src/main/resources/help_content.xml'
--- dhis-2/dhis-services/dhis-service-options/src/main/resources/help_content.xml	2010-09-24 13:23:08 +0000
+++ dhis-2/dhis-services/dhis-service-options/src/main/resources/help_content.xml	2010-10-24 15:41:13 +0000
@@ -555,6 +555,13 @@
       <para>To unarchive data, first enter a start date and an end date for the time span of the data which should be unarchived. Then press the unarchive button. The operation might take a few minutes.</para>
       <para>In some cases you might end up with overlapping data. For instance one might archive data for a given timespan, then later enter data for a period in that timespan. In such cases the system will automatically overwrite the oldest of the overlapping values with the newest during the archive or unarchive operation.</para>
     </section>
+	<section id="patientDataArchive">
+      <title>Patient Data Archive</title>
+      <para>The purpose of the patient data archive function is to move patient data value which is currently not being used for analysis to a secondary storage location in order to improve performance of the application. Data can be both archived and unarchived. When archiving data one moves it from the primary storage to the secondary storage location, while unarchiving moves it from the secondary storage location to the primary. Analysis functionality in DHIS 2 heavily utilizes queries to the data value database table, and by reducing the size of this table these operations will be significantly faster. Typically one would want to archive patient data that is older than two years.</para>
+      <para>To archive patient data, first enter a start date and an end date for the time span of the data which should be archived. Then press the archive button. The operation might take a few minutes.</para>
+      <para>To unarchive patient data, first enter a start date and an end date for the time span of the data which should be unarchived. Then press the unarchive button. The operation might take a few minutes.</para>
+      <para>In some cases you might end up with overlapping data. For instance one might archive patient data for a given timespan, then later enter data for a period in that timespan. In such cases the system will automatically overwrite the oldest of the overlapping values with the newest during the archive or unarchive operation.</para>
+    </section>
     <section id="maintenance">
       <title>Maintenance</title>
       <para>The data maintenance module has five options, each described below. </para>

=== modified file 'dhis-2/dhis-services/dhis-service-patient/src/main/resources/org/hisp/dhis/patientdatavalue/hibernate/PatientDataValue.hbm.xml'
--- dhis-2/dhis-services/dhis-service-patient/src/main/resources/org/hisp/dhis/patientdatavalue/hibernate/PatientDataValue.hbm.xml	2009-10-28 19:47:26 +0000
+++ dhis-2/dhis-services/dhis-service-patient/src/main/resources/org/hisp/dhis/patientdatavalue/hibernate/PatientDataValue.hbm.xml	2010-10-24 15:41:13 +0000
@@ -22,7 +22,7 @@
          
     <property name="providedByAnotherFacility" column="providedbyanotherfacility" not-null="true"/>
       
-    <property name="timestamp"/>
+    <property name="timestamp" type="date"/>
         
   </class>
 </hibernate-mapping>

=== modified file 'dhis-2/dhis-support/dhis-support-jdbc/src/main/java/org/hisp/dhis/jdbc/StatementBuilder.java'
--- dhis-2/dhis-support/dhis-support-jdbc/src/main/java/org/hisp/dhis/jdbc/StatementBuilder.java	2010-09-30 06:06:17 +0000
+++ dhis-2/dhis-support/dhis-support-jdbc/src/main/java/org/hisp/dhis/jdbc/StatementBuilder.java	2010-10-24 15:41:13 +0000
@@ -131,4 +131,16 @@
     String deleteOldestOverlappingDataValue();
     
     String deleteOldestOverlappingArchiveData();
+    
+    String archivePatientData ( String startDate, String endDate );
+    
+    String unArchivePatientData ( String startDate, String endDate );
+    
+    String deleteRegularOverlappingPatientData();
+    
+    String deleteArchivedOverlappingPatientData();
+    
+    String deleteOldestOverlappingPatientDataValue();
+    
+    String deleteOldestOverlappingPatientArchiveData();
 }

=== modified file 'dhis-2/dhis-support/dhis-support-jdbc/src/main/java/org/hisp/dhis/jdbc/statementbuilder/DerbyStatementBuilder.java'
--- dhis-2/dhis-support/dhis-support-jdbc/src/main/java/org/hisp/dhis/jdbc/statementbuilder/DerbyStatementBuilder.java	2010-09-30 06:06:17 +0000
+++ dhis-2/dhis-support/dhis-support-jdbc/src/main/java/org/hisp/dhis/jdbc/statementbuilder/DerbyStatementBuilder.java	2010-10-24 15:41:13 +0000
@@ -281,4 +281,67 @@
            "AND a.categoryoptioncomboid=d.categoryoptioncomboid " +
            "AND a.lastupdated<=d.lastupdated";
    }
+   
+   public String archivePatientData ( String startDate, String endDate )
+   {
+       return "DELETE FROM patientdatavalue AS pdv " 
+               + "USING programstageinstance AS psi ,  programinstance AS pi "
+               + "WHERE pdv.programstageinstanceid = psi.programstageinstanceid "
+               + "AND pi.programinstanceid = psi.programinstanceid "
+               + "WHERE pi.enddate >= '" + startDate + "' "
+               +    "AND pi.enddate <= '" +  endDate + "';";
+   }
+   
+   public String unArchivePatientData ( String startDate, String endDate )
+   {
+       return "DELETE FROM patientdatavaluearchive AS pdv " 
+               + "USING programstageinstance AS psi ,  programinstance AS pi "
+               + "WHERE pdv.programstageinstanceid = psi.programstageinstanceid "
+               + "AND pi.programinstanceid = psi.programinstanceid "
+               + "WHERE pi.enddate >= '" + startDate + "' "
+               +    "AND pi.enddate <= '" +  endDate + "';";
+   }
+
+   public String deleteRegularOverlappingPatientData()
+   {
+       return "DELETE FROM patientdatavalue AS d " +
+               "USING patientdatavaluearchive AS a " +
+               "WHERE d.programstageinstanceid=a.programstageinstanceid " +
+               "AND d.dataelementid=a.dataelementid " +
+               "AND d.organisationunitid=a.organisationunitid " +
+               "AND d.categoryoptioncomboid=a.categoryoptioncomboid " +
+               "AND d.timestamp<a.timestamp;";
+   }
+   
+   public String deleteArchivedOverlappingPatientData()
+   {
+       return "DELETE FROM patientdatavaluearchive AS a " +
+               "USING patientdatavalue AS d " +
+               "WHERE d.programstageinstanceid=a.programstageinstanceid " +
+               "AND d.dataelementid=a.dataelementid " +
+               "AND d.organisationunitid=a.organisationunitid " +
+               "AND d.categoryoptioncomboid=a.categoryoptioncomboid ";
+   }
+   
+   public String deleteOldestOverlappingPatientDataValue()
+   {
+       return "DELETE FROM patientdatavalue AS d " +
+               "USING patientdatavaluearchive AS a " +
+               "WHERE d.programstageinstanceid=a.programstageinstanceid " +
+               "AND d.dataelementid=a.dataelementid " +
+               "AND d.organisationunitid=a.organisationunitid " +
+               "AND d.categoryoptioncomboid=a.categoryoptioncomboid " +
+               "AND d.timestamp<a.timestamp;";
+   }
+   
+   public String deleteOldestOverlappingPatientArchiveData()
+   {
+       return "DELETE FROM patientdatavalue AS d " +
+               "USING patientdatavaluearchive AS a " +
+               "WHERE d.programstageinstanceid=a.programstageinstanceid " +
+               "AND d.dataelementid=a.dataelementid " +
+               "AND d.organisationunitid=a.organisationunitid " +
+               "AND d.categoryoptioncomboid=a.categoryoptioncomboid " +
+               "AND a.timestamp<=d.timestamp;";
+   }
 }

=== modified file 'dhis-2/dhis-support/dhis-support-jdbc/src/main/java/org/hisp/dhis/jdbc/statementbuilder/H2StatementBuilder.java'
--- dhis-2/dhis-support/dhis-support-jdbc/src/main/java/org/hisp/dhis/jdbc/statementbuilder/H2StatementBuilder.java	2010-10-01 09:05:32 +0000
+++ dhis-2/dhis-support/dhis-support-jdbc/src/main/java/org/hisp/dhis/jdbc/statementbuilder/H2StatementBuilder.java	2010-10-24 15:41:13 +0000
@@ -285,4 +285,67 @@
            "AND a.categoryoptioncomboid=d.categoryoptioncomboid " +
            "AND a.lastupdated<=d.lastupdated)";
     }
+    
+    public String archivePatientData ( String startDate, String endDate )
+    {
+        return "DELETE FROM patientdatavalue AS pdv " 
+                + "USING programstageinstance AS psi ,  programinstance AS pi "
+                + "WHERE pdv.programstageinstanceid = psi.programstageinstanceid "
+                + "AND pi.programinstanceid = psi.programinstanceid "
+                + "WHERE pi.enddate >= '" + startDate + "' "
+                +    "AND pi.enddate <= '" +  endDate + "';";
+    }
+    
+    public String unArchivePatientData ( String startDate, String endDate )
+    {
+        return "DELETE FROM patientdatavaluearchive AS pdv " 
+                + "USING programstageinstance AS psi ,  programinstance AS pi "
+                + "WHERE pdv.programstageinstanceid = psi.programstageinstanceid "
+                + "AND pi.programinstanceid = psi.programinstanceid "
+                + "WHERE pi.enddate >= '" + startDate + "' "
+                +    "AND pi.enddate <= '" +  endDate + "';";
+    }
+
+    public String deleteRegularOverlappingPatientData()
+    {
+        return "DELETE FROM patientdatavalue AS d " +
+                "USING patientdatavaluearchive AS a " +
+                "WHERE d.programstageinstanceid=a.programstageinstanceid " +
+                "AND d.dataelementid=a.dataelementid " +
+                "AND d.organisationunitid=a.organisationunitid " +
+                "AND d.categoryoptioncomboid=a.categoryoptioncomboid " +
+                "AND d.timestamp<a.timestamp;";
+    }
+    
+    public String deleteArchivedOverlappingPatientData()
+    {
+        return "DELETE FROM patientdatavaluearchive AS a " +
+                "USING patientdatavalue AS d " +
+                "WHERE d.programstageinstanceid=a.programstageinstanceid " +
+                "AND d.dataelementid=a.dataelementid " +
+                "AND d.organisationunitid=a.organisationunitid " +
+                "AND d.categoryoptioncomboid=a.categoryoptioncomboid ";
+    }
+    
+    public String deleteOldestOverlappingPatientDataValue()
+    {
+        return "DELETE FROM patientdatavalue AS d " +
+                "USING patientdatavaluearchive AS a " +
+                "WHERE d.programstageinstanceid=a.programstageinstanceid " +
+                "AND d.dataelementid=a.dataelementid " +
+                "AND d.organisationunitid=a.organisationunitid " +
+                "AND d.categoryoptioncomboid=a.categoryoptioncomboid " +
+                "AND d.timestamp<a.timestamp;";
+    }
+    
+    public String deleteOldestOverlappingPatientArchiveData()
+    {
+        return "DELETE FROM patientdatavalue AS d " +
+                "USING patientdatavaluearchive AS a " +
+                "WHERE d.programstageinstanceid=a.programstageinstanceid " +
+                "AND d.dataelementid=a.dataelementid " +
+                "AND d.organisationunitid=a.organisationunitid " +
+                "AND d.categoryoptioncomboid=a.categoryoptioncomboid " +
+                "AND a.timestamp<=d.timestamp;";
+    }
 }

=== modified file 'dhis-2/dhis-support/dhis-support-jdbc/src/main/java/org/hisp/dhis/jdbc/statementbuilder/MySQLStatementBuilder.java'
--- dhis-2/dhis-support/dhis-support-jdbc/src/main/java/org/hisp/dhis/jdbc/statementbuilder/MySQLStatementBuilder.java	2010-10-01 09:05:32 +0000
+++ dhis-2/dhis-support/dhis-support-jdbc/src/main/java/org/hisp/dhis/jdbc/statementbuilder/MySQLStatementBuilder.java	2010-10-24 15:41:13 +0000
@@ -281,4 +281,65 @@
            "AND a.categoryoptioncomboid=d.categoryoptioncomboid " +
            "AND a.lastupdated<=d.lastupdated";
    }
+   
+   public String archivePatientData ( String startDate, String endDate )
+   {
+       return "DELETE pdv FROM patientdatavalue AS pdv "
+                + "INNER JOIN programstageinstance AS psi "
+                +    "ON pdv.programstageinstanceid = psi.programstageinstanceid "
+                + "INNER JOIN programinstance AS pi "
+                +    "ON pi.programinstanceid = psi.programinstanceid "
+                + "WHERE pi.enddate >= '" + startDate + "' "
+                +    "AND pi.enddate <= '" +  endDate + "';";
+   }
+   
+   public String unArchivePatientData ( String startDate, String endDate )
+   {
+       return "DELETE pdv FROM patientdatavaluearchive AS pdv "
+               + "INNER JOIN programstageinstance AS psi "
+               +    "ON pdv.programstageinstanceid = psi.programstageinstanceid "
+               + "INNER JOIN programinstance AS pi "
+               +    "ON pi.programinstanceid = psi.programinstanceid "
+               + "WHERE pi.enddate >= '" + startDate + "' "
+               +    "AND pi.enddate <= '" +  endDate + "';";
+   }
+   
+   public String deleteRegularOverlappingPatientData(){
+       return "DELETE d FROM patientdatavalue AS d " +
+               "INNER JOIN patientdatavaluearchive AS a " +
+               "WHERE d.programstageinstanceid=a.programstageinstanceid " +
+               "AND d.dataelementid=a.dataelementid " +
+               "AND d.organisationunitid=a.organisationunitid " +
+               "AND d.categoryoptioncomboid=a.categoryoptioncomboid;";
+  }
+   
+  public String deleteArchivedOverlappingPatientData()
+  {
+      return "DELETE a FROM patientdatavaluearchive AS a " +
+              "INNER JOIN patientdatavalue AS d " +
+              "WHERE d.programstageinstanceid=a.programstageinstanceid " +
+              "AND d.dataelementid=a.dataelementid " +
+              "AND d.organisationunitid=a.organisationunitid " +
+              "AND d.categoryoptioncomboid=a.categoryoptioncomboid ";
+  }
+   
+  public String deleteOldestOverlappingPatientDataValue(){
+       return "DELETE d FROM patientdatavalue AS d " +
+               "INNER JOIN patientdatavaluearchive AS a " +
+               "WHERE d.programstageinstanceid=a.programstageinstanceid " +
+               "AND d.dataelementid=a.dataelementid " +
+               "AND d.organisationunitid=a.organisationunitid " +
+               "AND d.categoryoptioncomboid=a.categoryoptioncomboid " +
+               "AND d.timestamp<a.timestamp;";
+   }
+   
+   public String deleteOldestOverlappingPatientArchiveData(){
+       return "DELETE a FROM patientdatavaluearchive AS a " +
+               "INNER JOIN patientdatavalue AS d " +
+               "WHERE d.programstageinstanceid=a.programstageinstanceid " +
+               "AND d.dataelementid=a.dataelementid " +
+               "AND d.organisationunitid=a.organisationunitid " +
+               "AND d.categoryoptioncomboid=a.categoryoptioncomboid " +
+               "AND a.timestamp<=d.timestamp;";
+   }
 }

=== modified file 'dhis-2/dhis-support/dhis-support-jdbc/src/main/java/org/hisp/dhis/jdbc/statementbuilder/PostgreSQLStatementBuilder.java'
--- dhis-2/dhis-support/dhis-support-jdbc/src/main/java/org/hisp/dhis/jdbc/statementbuilder/PostgreSQLStatementBuilder.java	2010-10-01 09:05:32 +0000
+++ dhis-2/dhis-support/dhis-support-jdbc/src/main/java/org/hisp/dhis/jdbc/statementbuilder/PostgreSQLStatementBuilder.java	2010-10-24 15:41:13 +0000
@@ -283,4 +283,66 @@
           "AND a.categoryoptioncomboid=d.categoryoptioncomboid " +
           "AND a.lastupdated<=d.lastupdated";
     }
+    
+    public String archivePatientData ( String startDate, String endDate )
+    {
+        return "DELETE FROM patientdatavalue AS pdv " 
+                + "USING programstageinstance AS psi ,  programinstance AS pi "
+                + "WHERE pdv.programstageinstanceid = psi.programstageinstanceid "
+                + "AND pi.programinstanceid = psi.programinstanceid "
+                + "AND pi.enddate >= '" + startDate + "' "
+                +    "AND pi.enddate <= '" +  endDate + "';";
+    }
+    
+    public String unArchivePatientData ( String startDate, String endDate )
+    {
+        return "DELETE FROM patientdatavaluearchive AS pdv " 
+                + "USING programstageinstance AS psi ,  programinstance AS pi "
+                + "WHERE pdv.programstageinstanceid = psi.programstageinstanceid "
+                + "AND pi.programinstanceid = psi.programinstanceid "
+                + "AND pi.enddate >= '" + startDate + "' "
+                +    "AND pi.enddate <= '" +  endDate + "';";
+    }
+    
+    public String deleteRegularOverlappingPatientData()
+    {
+        return "DELETE FROM patientdatavalue AS d " +
+                "USING patientdatavaluearchive AS a " +
+                "WHERE d.programstageinstanceid=a.programstageinstanceid " +
+                "AND d.dataelementid=a.dataelementid " +
+                "AND d.organisationunitid=a.organisationunitid " +
+                "AND d.categoryoptioncomboid=a.categoryoptioncomboid ";
+    }
+    
+    public String deleteArchivedOverlappingPatientData()
+    {
+        return "DELETE FROM patientdatavaluearchive AS a " +
+                "USING patientdatavalue AS d " +
+                "WHERE d.programstageinstanceid=a.programstageinstanceid " +
+                "AND d.dataelementid=a.dataelementid " +
+                "AND d.organisationunitid=a.organisationunitid " +
+                "AND d.categoryoptioncomboid=a.categoryoptioncomboid ";
+    }
+    
+    public String deleteOldestOverlappingPatientDataValue()
+    {
+        return "DELETE FROM patientdatavalue AS d " +
+                "USING patientdatavaluearchive AS a " +
+                "WHERE d.programstageinstanceid=a.programstageinstanceid " +
+                "AND d.dataelementid=a.dataelementid " +
+                "AND d.organisationunitid=a.organisationunitid " +
+                "AND d.categoryoptioncomboid=a.categoryoptioncomboid " +
+                "AND d.timestamp<a.timestamp;";
+    }
+    
+    public String deleteOldestOverlappingPatientArchiveData()
+    {
+        return "DELETE FROM patientdatavalue AS d " +
+                "USING patientdatavaluearchive AS a " +
+                "WHERE d.programstageinstanceid=a.programstageinstanceid " +
+                "AND d.dataelementid=a.dataelementid " +
+                "AND d.organisationunitid=a.organisationunitid " +
+                "AND d.categoryoptioncomboid=a.categoryoptioncomboid " +
+                "AND a.timestamp<=d.timestamp;";
+    }
 }

=== modified file 'dhis-2/dhis-web/dhis-web-caseentry/src/main/java/org/hisp/dhis/caseentry/action/caseentry/CompleteDataEntryAction.java'
--- dhis-2/dhis-web/dhis-web-caseentry/src/main/java/org/hisp/dhis/caseentry/action/caseentry/CompleteDataEntryAction.java	2010-02-22 09:19:15 +0000
+++ dhis-2/dhis-web/dhis-web-caseentry/src/main/java/org/hisp/dhis/caseentry/action/caseentry/CompleteDataEntryAction.java	2010-10-24 15:41:13 +0000
@@ -38,8 +38,6 @@
  */
 public class CompleteDataEntryAction implements Action
 {
-   
-
     // -------------------------------------------------------------------------
     // Dependencies
     // -------------------------------------------------------------------------

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/resources/META-INF/dhis/beans.xml'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/resources/META-INF/dhis/beans.xml	2010-10-21 05:41:06 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/resources/META-INF/dhis/beans.xml	2010-10-24 15:41:13 +0000
@@ -202,6 +202,12 @@
 		scope="prototype">
 		<property name="dataArchiveService" ref="org.hisp.dhis.dataarchive.DataArchiveService" />
 	</bean>
+	
+	<bean id="org.hisp.dhis.dataadmin.action.dataarchive.ArchivePatientDataAction"
+		class="org.hisp.dhis.dataadmin.action.dataarchive.ArchivePatientDataAction"
+		scope="prototype">
+		<property name="dataArchiveService" ref="org.hisp.dhis.dataarchive.DataArchiveService" />
+	</bean>
 
 	<bean
 		id="org.hisp.dhis.dataadmin.action.dataarchive.GetNumberOfOverlapsAction"
@@ -209,6 +215,13 @@
 		scope="prototype">
 		<property name="dataArchiveService" ref="org.hisp.dhis.dataarchive.DataArchiveService" />
 	</bean>
+	
+	<bean
+		id="org.hisp.dhis.dataadmin.action.dataarchive.GetNumberOfOverlapingPatientValuesAction"
+		class="org.hisp.dhis.dataadmin.action.dataarchive.GetNumberOfOverlapingPatientValuesAction"
+		scope="prototype">
+		<property name="dataArchiveService" ref="org.hisp.dhis.dataarchive.DataArchiveService" />
+	</bean>
 
 	<!-- Min/Max validation -->
 

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/resources/org/hisp/dhis/dataadmin/i18n_module.properties'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/resources/org/hisp/dhis/dataadmin/i18n_module.properties	2010-10-21 05:41:06 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/resources/org/hisp/dhis/dataadmin/i18n_module.properties	2010-10-24 15:41:13 +0000
@@ -314,4 +314,6 @@
 portrait                                                            = Portrait
 data_set_list                                                       = Data Set list
 data_element_group_list                                             = Data Element Group list
-orgunit_group_list                                                  = Organisation Unit Group list
\ No newline at end of file
+orgunit_group_list                                                  = Organisation Unit Group list
+patient_data_archive												= Patient Data Archive
+intro__patient_data_archive											= Archive patient data which is not currently relevant to your system in order to improve performance. Data can also be unarchived.
\ No newline at end of file

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/resources/struts.xml'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/resources/struts.xml	2010-10-05 10:04:27 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/resources/struts.xml	2010-10-24 15:41:13 +0000
@@ -281,6 +281,27 @@
 				/dhis-web-maintenance-dataadmin/responseNumber.vm</result>
 		</action>
 		
+		<action name="displayPatientDataArchiveForm"
+			class="org.hisp.dhis.dataadmin.action.NoAction">
+			<result name="success" type="velocity">/main.vm</result>
+			<param name="page">
+				/dhis-web-maintenance-dataadmin/patientDataArchiveForm.vm</param>
+			<param name="menu">/dhis-web-maintenance-dataadmin/menu.vm</param>
+			<param name="javascripts">javascript/dataArchive.js</param>
+		</action>
+		
+		<action name="archivePatientData"
+			class="org.hisp.dhis.dataadmin.action.dataarchive.ArchivePatientDataAction">
+			<result name="success" type="velocity-json">
+				/dhis-web-maintenance-dataadmin/responseNumber.vm</result>
+		</action>
+		
+		<action name="getNumberOfOverlapingPatientValues"
+			class="org.hisp.dhis.dataadmin.action.dataarchive.GetNumberOfOverlapingPatientValuesAction">
+			<result name="success" type="velocity-json">
+				/dhis-web-maintenance-dataadmin/responseNumber.vm</result>
+		</action>
+		
 		<!-- Min/Max validation -->
 		
 		<action name="generateMinMaxValue"

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/webapp/dhis-web-maintenance-dataadmin/index.vm'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/webapp/dhis-web-maintenance-dataadmin/index.vm	2010-07-16 08:26:19 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/webapp/dhis-web-maintenance-dataadmin/index.vm	2010-10-24 15:41:13 +0000
@@ -5,6 +5,7 @@
     #introListImgItem( "displayDataBrowserForm.action" "data_browser" "databrowser" )
     #introListImgItem( "displayDataIntegrityForm.action" "data_integrity" "dataintegrity" )
     #introListImgItem( "displayDataArchiveForm.action" "data_archive" "dataarchive" )
+	#introListImgItem( "displayPatientDataArchiveForm.action" "patient_data_archive" "dataarchive" )
     #introListImgItem( "displayMaintenanceForm.action" "maintenance" "maintenance" )
     #introListImgItem( "displayResourceTableForm.action" "resource_table" "resourcetable" )
     #introListImgItem( "showSqlViewListForm.action" "sql_view" "sqlview" )

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/webapp/dhis-web-maintenance-dataadmin/javascript/dataArchive.js'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/webapp/dhis-web-maintenance-dataadmin/javascript/dataArchive.js	2010-02-01 20:21:20 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/webapp/dhis-web-maintenance-dataadmin/javascript/dataArchive.js	2010-10-24 15:41:13 +0000
@@ -45,3 +45,28 @@
         }
     );
 }
+
+function patientArchive( operation )
+{
+	var startDate = $( "#startDate" ).val();
+	var endDate = $( "#endDate" ).val();
+    var strategy = $( "input[name='strategy']:checked" ).val();
+    
+    var message = operation == "archive" ? i18n_archiving : i18n_unarchiving;
+    
+    setWaitMessage( message );
+    
+    $.getJSON( 
+        "archivePatientData.action",
+        {
+        	"startDate": startDate,
+        	"endDate": endDate,
+        	"operation": operation,
+        	"strategy": strategy
+        },
+        function( json )
+        {
+        	setMessage( message + " " + i18n_done_number_of_values + " " + json.number + "." );
+        }
+    );
+}

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/webapp/dhis-web-maintenance-dataadmin/menu.vm'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/webapp/dhis-web-maintenance-dataadmin/menu.vm	2010-07-16 08:26:19 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/webapp/dhis-web-maintenance-dataadmin/menu.vm	2010-10-24 15:41:13 +0000
@@ -4,6 +4,7 @@
 		<li><a href="displayDataBrowserForm.action">$i18n.getString( "data_browser" )&nbsp;</a></li>
         <li><a href="displayDataIntegrityForm.action">$i18n.getString( "data_integrity" )&nbsp;</a></li>
         <li><a href="displayDataArchiveForm.action">$i18n.getString( "data_archive" )&nbsp;</a></li>
+		<li><a href="displayPatientDataArchiveForm.action">$i18n.getString( "patient_data_archive" )&nbsp;</a></li>
 		<li><a href="displayMaintenanceForm.action">$i18n.getString( "maintenance" )&nbsp;</a></li>
 		<li><a href="displayResourceTableForm.action">$i18n.getString( "resource_table" )&nbsp;</a></li>
 		<li><a href="showSqlViewListForm.action">$i18n.getString( "sql_view" )&nbsp;</a></li>