diff --git a/.travis.yml b/.travis.yml index f5995e047b..7b2e6b56b3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,7 +26,7 @@ branches: - develop script: -- travis_wait 60 "./build.sh" +- travis_wait 70 "./build.sh" before_script: - echo no | android create avd --force -n test -t android-22 --abi armeabi-v7a diff --git a/build.gradle b/build.gradle index a1dd895f24..df225c0f23 100644 --- a/build.gradle +++ b/build.gradle @@ -54,8 +54,8 @@ ext { buildToolsVersion: "25.0.2", minSdkVersion : 15, targetSdkVersion : 25, - versionCode : 43_1, - versionName : "0.4.3.1-SNAPSHOT" + versionCode : 50, + versionName : "0.5-SNAPSHOT" ] libraries = [ diff --git a/core/src/androidTest/assets/admin/data_values.json b/core/src/androidTest/assets/admin/data_values.json new file mode 100644 index 0000000000..4473304352 --- /dev/null +++ b/core/src/androidTest/assets/admin/data_values.json @@ -0,0 +1,17 @@ +{ + "dataValues": [ + { + "dataElement": "g9eOBujte1U", + "period": "201712", + "orgUnit": "Rp268JB6Ne4", + "categoryOptionCombo": "Gmbgme7z9BF", + "attributeOptionCombo": "bRowv6yZOF2", + "value": "12", + "storedBy": "bodata1", + "created": "2011-01-11T00:00:00.000+0000", + "lastUpdated": "2011-01-11T00:00:00.000+0000", + "comment": "", + "followUp": false + } + ] +} \ No newline at end of file diff --git a/core/src/androidTest/assets/admin/organisation_units.json b/core/src/androidTest/assets/admin/organisation_units.json index a0176e85a5..646d82acb0 100644 --- a/core/src/androidTest/assets/admin/organisation_units.json +++ b/core/src/androidTest/assets/admin/organisation_units.json @@ -46,6 +46,11 @@ { "id": "WSGAb5XwJ3Y" } + ], + "dataSets": [ + { + "id": "lyLU2wR22tC" + } ] }, { @@ -94,6 +99,11 @@ { "id": "WSGAb5XwJ3Y" } + ], + "dataSets": [ + { + "id": "lyLU2wR22tC" + } ] } ] diff --git a/core/src/androidTest/assets/data_sets.json b/core/src/androidTest/assets/data_sets.json index b1f327807c..21e3caa2cd 100644 --- a/core/src/androidTest/assets/data_sets.json +++ b/core/src/androidTest/assets/data_sets.json @@ -32,7 +32,21 @@ "id": "g9eOBujte1U" } } - ] + ], + "indicators": [ + { + "id": "ReUHfIn0pTQ" + } + ], + "access": { + "data": { + "write": true + } + }, + "style": { + "color": "#000", + "icon": "my-icon-name" + } } ] } \ No newline at end of file diff --git a/core/src/androidTest/assets/data_values.json b/core/src/androidTest/assets/data_values.json new file mode 100644 index 0000000000..7de3e7657c --- /dev/null +++ b/core/src/androidTest/assets/data_values.json @@ -0,0 +1,17 @@ +{ + "dataValues": [ + { + "dataElement": "g9eOBujte1U", + "period": "201712", + "orgUnit": "DiszpKrYNg8", + "categoryOptionCombo": "Gmbgme7z9BF", + "attributeOptionCombo": "bRowv6yZOF2", + "value": "12", + "storedBy": "bodata1", + "created": "2011-01-11T00:00:00.000+0000", + "lastUpdated": "2011-01-11T00:00:00.000+0000", + "comment": "", + "followUp": false + } + ] +} \ No newline at end of file diff --git a/core/src/androidTest/assets/indicator_types.json b/core/src/androidTest/assets/indicator_types.json new file mode 100644 index 0000000000..5170c4b2f6 --- /dev/null +++ b/core/src/androidTest/assets/indicator_types.json @@ -0,0 +1,13 @@ +{ + "indicatorTypes": [ + { + "created": "2011-12-24T12:24:22.592", + "lastUpdated": "2013-03-15T16:08:57.670", + "name": "Per cent", + "id": "bWuNrMHEoZ0", + "displayName": "Per cent", + "number": false, + "factor": 100 + } + ] +} \ No newline at end of file diff --git a/core/src/androidTest/assets/indicators.json b/core/src/androidTest/assets/indicators.json new file mode 100644 index 0000000000..aa16ed8d50 --- /dev/null +++ b/core/src/androidTest/assets/indicators.json @@ -0,0 +1,24 @@ +{ + "indicators": [ + { + "code": "IN_52462", + "lastUpdated": "2013-03-21T11:17:44.926", + "id": "ReUHfIn0pTQ", + "created": "2012-11-05T09:16:29.054", + "name": "ANC 1-3 Dropout Rate", + "shortName": "ANC 1-3 Dropout Rate", + "displayName": "ANC 1-3 Dropout Rate", + "description": "Indicates the percentage of clients dropping out between the 1st and the 3rd ANC visit. Calculated as the difference between ANC1 and ANC3 by the ANC 1 visits.", + "denominatorDescription": "Total 1st ANC visits", + "numeratorDescription": "ANC1-ANC3", + "displayDescription": "Indicates the percentage of clients dropping out between the 1st and the 3rd ANC visit. Calculated as the difference between ANC1 and ANC3 by the ANC 1 visits.", + "url": "", + "numerator": "#{fbfJHSPpUQD.pq2XI5kz2BY}+#{fbfJHSPpUQD.PT59n8BQbqM}-#{Jtf34kNZhzP.pq2XI5kz2BY}-#{Jtf34kNZhzP.PT59n8BQbqM}", + "denominator": "#{fbfJHSPpUQD.pq2XI5kz2BY}+#{fbfJHSPpUQD.PT59n8BQbqM}", + "annualized": false, + "indicatorType": { + "id": "bWuNrMHEoZ0" + } + } + ] +} \ No newline at end of file diff --git a/core/src/androidTest/assets/organisationUnits.json b/core/src/androidTest/assets/organisationUnits.json index e62277187f..4b83c0220f 100644 --- a/core/src/androidTest/assets/organisationUnits.json +++ b/core/src/androidTest/assets/organisationUnits.json @@ -49,6 +49,11 @@ { "id": "fDd25txQckK" } + ], + "dataSets": [ + { + "id": "lyLU2wR22tC" + } ] } ] diff --git a/core/src/androidTest/assets/programs.json b/core/src/androidTest/assets/programs.json index caf252db85..1081f1e277 100644 --- a/core/src/androidTest/assets/programs.json +++ b/core/src/androidTest/assets/programs.json @@ -22,6 +22,11 @@ "selectEnrollmentDatesInFuture": false, "registration": false, "useFirstStageDuringRegistration": false, + "access": { + "data": { + "write": true + } + }, "programRuleVariables": [ { "created": "2016-04-12T15:57:18.645", @@ -270,6 +275,11 @@ "selectEnrollmentDatesInFuture": false, "registration": true, "useFirstStageDuringRegistration": true, + "access": { + "data": { + "write": true + } + }, "trackedEntity": { "id": "nEenWmSyUEp" }, @@ -1429,6 +1439,11 @@ "selectEnrollmentDatesInFuture": false, "registration": false, "useFirstStageDuringRegistration": false, + "access": { + "data": { + "write": true + } + }, "programRuleVariables": [], "programTrackedEntityAttributes": [], "programIndicators": [], @@ -1679,6 +1694,11 @@ "selectEnrollmentDatesInFuture": false, "registration": false, "useFirstStageDuringRegistration": false, + "access": { + "data": { + "write": true + } + }, "programRuleVariables": [], "programTrackedEntityAttributes": [], "programIndicators": [], @@ -1924,6 +1944,11 @@ "selectEnrollmentDatesInFuture": false, "registration": false, "useFirstStageDuringRegistration": false, + "access": { + "data": { + "write": true + } + }, "programRuleVariables": [ { "created": "2015-08-07T18:38:12.931", @@ -2786,6 +2811,11 @@ "selectEnrollmentDatesInFuture": false, "registration": false, "useFirstStageDuringRegistration": false, + "access": { + "data": { + "write": true + } + }, "programRuleVariables": [], "programTrackedEntityAttributes": [], "programIndicators": [ @@ -2947,6 +2977,11 @@ "selectEnrollmentDatesInFuture": false, "registration": false, "useFirstStageDuringRegistration": false, + "access": { + "data": { + "write": true + } + }, "programRuleVariables": [], "programTrackedEntityAttributes": [], "programIndicators": [], @@ -3109,6 +3144,11 @@ "selectEnrollmentDatesInFuture": false, "registration": true, "useFirstStageDuringRegistration": false, + "access": { + "data": { + "write": true + } + }, "trackedEntity": { "id": "nEenWmSyUEp" }, @@ -5127,6 +5167,11 @@ "selectEnrollmentDatesInFuture": false, "registration": true, "useFirstStageDuringRegistration": false, + "access": { + "data": { + "write": true + } + }, "trackedEntity": { "id": "nEenWmSyUEp" }, @@ -7402,6 +7447,11 @@ "selectEnrollmentDatesInFuture": false, "registration": true, "useFirstStageDuringRegistration": false, + "access": { + "data": { + "write": true + } + }, "trackedEntity": { "id": "nEenWmSyUEp" }, @@ -8735,6 +8785,11 @@ "selectEnrollmentDatesInFuture": false, "registration": true, "useFirstStageDuringRegistration": false, + "access": { + "data": { + "write": true + } + }, "trackedEntity": { "id": "nEenWmSyUEp" }, diff --git a/core/src/androidTest/assets/programs_complete.json b/core/src/androidTest/assets/programs_complete.json index 62f85d69ad..dd855384ba 100644 --- a/core/src/androidTest/assets/programs_complete.json +++ b/core/src/androidTest/assets/programs_complete.json @@ -29,6 +29,15 @@ "selectEnrollmentDatesInFuture": false, "registration": true, "useFirstStageDuringRegistration": true, + "access": { + "data": { + "write": false + } + }, + "style": { + "color": "#fff", + "icon": "my-icon-name" + }, "trackedEntity": { "id": "nEenWmSyUEp" }, @@ -103,7 +112,24 @@ "inherit": false, "unique": false, "valueType": "TEXT", - "orgunitScope": false + "orgunitScope": false, + "renderType": { + "DESKTOP": { + "type": "SPINNER", + "min": 5, + "max": 600, + "step": 4, + "decimalPoints": 3 + }, + "MOBILE": { + "type": "SLIDER", + "min": 555, + "max": 88888, + "step": 77, + "decimalPoints": 1 + } + } + } }, { @@ -585,7 +611,22 @@ } } ], - "programStageSections": [ ] + "programStageSections": [ + { + "id": "OeSqs7pkKqI", + "dataElements": [ + + ], + "renderType": { + "DESKTOP": { + "type": "SEQUENTIAL" + }, + "MOBILE": { + "type": "MATRIX" + } + } + } + ] }, { "lastUpdated": "2015-08-06T20:16:48.321", diff --git a/core/src/androidTest/assets/tracked_entities.json b/core/src/androidTest/assets/tracked_entities.json index a6e1630fa8..6f132fcb85 100644 --- a/core/src/androidTest/assets/tracked_entities.json +++ b/core/src/androidTest/assets/tracked_entities.json @@ -1,5 +1,5 @@ { - "trackedEntities": [ + "trackedEntityTypes": [ { "lastUpdated": "2015-10-14T13:36:53.063", "created": "2014-08-20T12:28:56.409", diff --git a/core/src/androidTest/assets/tracked_entity_instance.json b/core/src/androidTest/assets/tracked_entity_instance.json index f5a0eb4fb9..5fa1677ca2 100644 --- a/core/src/androidTest/assets/tracked_entity_instance.json +++ b/core/src/androidTest/assets/tracked_entity_instance.json @@ -1,5 +1,5 @@ { - "trackedEntity": "nEenWmSyUEp", + "trackedEntityType": "nEenWmSyUEp", "orgUnit": "DiszpKrYNg8", "trackedEntityInstance": "PgmUFEQYZdt", "deleted": false, diff --git a/core/src/androidTest/assets/tracked_entity_instance_2.json b/core/src/androidTest/assets/tracked_entity_instance_2.json index 3ce9229e01..690ecedaf0 100644 --- a/core/src/androidTest/assets/tracked_entity_instance_2.json +++ b/core/src/androidTest/assets/tracked_entity_instance_2.json @@ -1,5 +1,5 @@ { - "trackedEntity": "nEenWmSyUEp", + "trackedEntityType": "nEenWmSyUEp", "orgUnit": "DiszpKrYNg8", "trackedEntityInstance": "IaxoagO9899", "deleted": false, diff --git a/core/src/androidTest/assets/tracked_entity_instance_with_removed_data.json b/core/src/androidTest/assets/tracked_entity_instance_with_removed_data.json index c1db4f0221..01504a2f9c 100644 --- a/core/src/androidTest/assets/tracked_entity_instance_with_removed_data.json +++ b/core/src/androidTest/assets/tracked_entity_instance_with_removed_data.json @@ -1,5 +1,5 @@ { - "trackedEntity": "nEenWmSyUEp", + "trackedEntityType": "nEenWmSyUEp", "orgUnit": "DiszpKrYNg8", "trackedEntityInstance": "PgmUFEQYZdt", "deleted": false, diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/LogoutCallMockIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/LogoutCallMockIntegrationShould.java index 36775023a0..4036321327 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/LogoutCallMockIntegrationShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/LogoutCallMockIntegrationShould.java @@ -182,32 +182,14 @@ private void givenALoginWithSierraLeonaOUInDatabase() throws Exception { } private void givenAMetadataInDatabase() throws Exception { - dhis2MockServer.enqueueMockResponse("system_info.json"); - dhis2MockServer.enqueueMockResponse("user.json"); - dhis2MockServer.enqueueMockResponse("organisationUnits.json"); - dhis2MockServer.enqueueMockResponse("categories.json"); - dhis2MockServer.enqueueMockResponse("category_combos.json"); - dhis2MockServer.enqueueMockResponse("programs.json"); - dhis2MockServer.enqueueMockResponse("tracked_entities.json"); - dhis2MockServer.enqueueMockResponse("option_sets.json"); - dhis2MockServer.enqueueMockResponse("data_sets.json"); - dhis2MockServer.enqueueMockResponse("data_elements.json"); + dhis2MockServer.enqueueMetadataResponses(); Response response = d2.syncMetaData().call(); assertThat(response.isSuccessful(), is(true)); } private void givenAMetadataWithDescendantsInDatabase() throws Exception { - dhis2MockServer.enqueueMockResponse("system_info.json"); - dhis2MockServer.enqueueMockResponse("admin/user.json"); - dhis2MockServer.enqueueMockResponse("admin/organisation_units.json"); - dhis2MockServer.enqueueMockResponse("categories.json"); - dhis2MockServer.enqueueMockResponse("category_combos.json"); - dhis2MockServer.enqueueMockResponse("programs.json"); - dhis2MockServer.enqueueMockResponse("tracked_entities.json"); - dhis2MockServer.enqueueMockResponse("option_sets.json"); - dhis2MockServer.enqueueMockResponse("data_sets.json"); - dhis2MockServer.enqueueMockResponse("data_elements.json"); + dhis2MockServer.enqueueMetadataWithDescendentsResponses(); Response response = d2.syncMetaData().call(); diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/MetadataCallRealIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/MetadataCallRealIntegrationShould.java index 7ef571e31d..0d0425044e 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/MetadataCallRealIntegrationShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/MetadataCallRealIntegrationShould.java @@ -48,6 +48,7 @@ make a debugger break point where desired (after sync complete) //@Test public void response_successful_on_sync_meta_data_two_times() throws Exception { retrofit2.Response response = null; + d2.logout().call(); response = d2.logIn("android", "Android123").call(); assertThat(response.isSuccessful()).isTrue(); diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/SingleDataCallMockIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/SingleDataCallMockIntegrationShould.java index 86ec93ccde..4b9eb1da48 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/SingleDataCallMockIntegrationShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/SingleDataCallMockIntegrationShould.java @@ -64,16 +64,7 @@ public void download_number_of_events_according_to_limit_by_org_unit() throws Ex } private void givenAMetadataInDatabase() throws Exception { - dhis2MockServer.enqueueMockResponse("system_info.json"); - dhis2MockServer.enqueueMockResponse("user.json"); - dhis2MockServer.enqueueMockResponse("organisationUnits.json"); - dhis2MockServer.enqueueMockResponse("categories.json"); - dhis2MockServer.enqueueMockResponse("category_combos.json"); - dhis2MockServer.enqueueMockResponse("programs.json"); - dhis2MockServer.enqueueMockResponse("tracked_entities.json"); - dhis2MockServer.enqueueMockResponse("option_sets.json"); - dhis2MockServer.enqueueMockResponse("data_sets.json"); - dhis2MockServer.enqueueMockResponse("data_elements.json"); + dhis2MockServer.enqueueMetadataResponses(); d2.syncMetaData().call(); } } diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/TrackerDataCallMockIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/TrackerDataCallMockIntegrationShould.java index 4721ad9986..bc9fe5e2bf 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/TrackerDataCallMockIntegrationShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/TrackerDataCallMockIntegrationShould.java @@ -181,16 +181,7 @@ private void verifyHaveNotSynchronized(Response response, } private void givenAMetadataInDatabase() throws Exception { - dhis2MockServer.enqueueMockResponse("system_info.json"); - dhis2MockServer.enqueueMockResponse("user.json"); - dhis2MockServer.enqueueMockResponse("organisationUnits.json"); - dhis2MockServer.enqueueMockResponse("categories.json"); - dhis2MockServer.enqueueMockResponse("category_combos.json"); - dhis2MockServer.enqueueMockResponse("programs.json"); - dhis2MockServer.enqueueMockResponse("tracked_entities.json"); - dhis2MockServer.enqueueMockResponse("option_sets.json"); - dhis2MockServer.enqueueMockResponse("data_sets.json"); - dhis2MockServer.enqueueMockResponse("data_elements.json"); + dhis2MockServer.enqueueMetadataResponses(); d2.syncMetaData().call(); } diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/common/ModelAbstractShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/common/ModelAbstractShould.java index 9805a9b09a..0c5188aecb 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/common/ModelAbstractShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/common/ModelAbstractShould.java @@ -35,8 +35,8 @@ public abstract class ModelAbstractShould extends LinkModelAbstractShould { protected final M model; - protected final P pojo; - protected final ModelFactory modelFactory; + private final P pojo; + private final ModelFactory modelFactory; public ModelAbstractShould(String[] columns, int columnsLength, ModelFactory modelFactory) { super(columns, columnsLength, modelFactory); diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/common/StoreMocks.java b/core/src/androidTest/java/org/hisp/dhis/android/core/common/StoreMocks.java index 6ac82af8e8..4dca6e5c98 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/common/StoreMocks.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/common/StoreMocks.java @@ -8,8 +8,8 @@ import static org.hisp.dhis.android.core.data.database.CursorAssert.assertThatCursor; -public class StoreMocks { - public static OptionSetModel generateOptionSetModel() { +class StoreMocks { + static OptionSetModel generateOptionSetModel() { return OptionSetModel.builder() .uid("1234567890") .code("code") @@ -22,7 +22,7 @@ public static OptionSetModel generateOptionSetModel() { .build(); } - public static OptionSetModel generateUpdatedOptionSetModel() { + static OptionSetModel generateUpdatedOptionSetModel() { return OptionSetModel.builder() .uid("1234567890") .code("updated_code") @@ -35,7 +35,7 @@ public static OptionSetModel generateUpdatedOptionSetModel() { .build(); } - public static OptionSetModel generateOptionSetModelWithoutUid() { + static OptionSetModel generateOptionSetModelWithoutUid() { return OptionSetModel.builder() .uid(null) .code("code") @@ -48,7 +48,7 @@ public static OptionSetModel generateOptionSetModelWithoutUid() { .build(); } - public static void optionSetCursorAssert(Cursor cursor, OptionSetModel m) { + static void optionSetCursorAssert(Cursor cursor, OptionSetModel m) { assertThatCursor(cursor).hasRow( m.uid(), m.code(), diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/common/ValueTypeDeviceRenderingModelShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/common/ValueTypeDeviceRenderingModelShould.java new file mode 100644 index 0000000000..b7827ca52f --- /dev/null +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/common/ValueTypeDeviceRenderingModelShould.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2017, University of Oslo + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.hisp.dhis.android.core.common; + +import android.support.test.runner.AndroidJUnit4; + +import org.hisp.dhis.android.core.common.ValueTypeDeviceRenderingModel.Columns; +import org.hisp.dhis.android.core.utils.ColumnsArrayUtils; +import org.hisp.dhis.android.core.utils.Utils; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.Arrays; +import java.util.List; + +import static com.google.common.truth.Truth.assertThat; +import static org.hisp.dhis.android.core.data.utils.FillPropertiesTestUtils.DEVICE_TYPE; +import static org.hisp.dhis.android.core.data.utils.FillPropertiesTestUtils.TABLE; +import static org.hisp.dhis.android.core.data.utils.FillPropertiesTestUtils.UID; +import static org.hisp.dhis.android.core.data.utils.FillPropertiesTestUtils.VALUE_TYPE_RENDERING_TYPE; + +@RunWith(AndroidJUnit4.class) +public class ValueTypeDeviceRenderingModelShould extends LinkModelAbstractShould { + + public ValueTypeDeviceRenderingModelShould() { + super(Columns.all(), 8, ValueTypeDeviceRenderingModel.factory); + } + + @Override + protected ValueTypeDeviceRenderingModel buildModel() { + ValueTypeDeviceRenderingModel.Builder valueTypeDeviceRenderingModelBuilder = + ValueTypeDeviceRenderingModel.builder(); + valueTypeDeviceRenderingModelBuilder + .uid(UID) + .objectTable(TABLE) + .deviceType(DEVICE_TYPE) + .type(VALUE_TYPE_RENDERING_TYPE) + .min(0) + .max(10) + .step(1) + .decimalPoints(0); + return valueTypeDeviceRenderingModelBuilder.build(); + } + + @Override + protected Object[] getModelAsObjectArray() { + return Utils.appendInNewArray(ColumnsArrayUtils.getModelAsObjectArray(model), + model.uid(), model.objectTable(), model.deviceType(), model.type(), model.min(), model.max(), + model.step(), model.decimalPoints()); + } + + private ValueTypeDeviceRendering buildPojo() { + return ValueTypeDeviceRendering.create(VALUE_TYPE_RENDERING_TYPE, 0, 10, 1, 0); + } + + @Test + public void create_model_from_pojo() { + assertThat(ValueTypeDeviceRenderingModel.fromPojo(buildPojo(), UID, TABLE, DEVICE_TYPE)).isEqualTo(model); + } + + @Test + public void have_value_type_device_rendering_model_columns() { + List columnsList = Arrays.asList(columns); + + assertThat(columnsList.contains(Columns.UID)).isEqualTo(true); + assertThat(columnsList.contains(Columns.OBJECT_TABLE)).isEqualTo(true); + assertThat(columnsList.contains(Columns.DEVICE_TYPE)).isEqualTo(true); + assertThat(columnsList.contains(Columns.TYPE)).isEqualTo(true); + assertThat(columnsList.contains(Columns.MAX)).isEqualTo(true); + assertThat(columnsList.contains(Columns.MIN)).isEqualTo(true); + assertThat(columnsList.contains(Columns.STEP)).isEqualTo(true); + assertThat(columnsList.contains(Columns.DECIMAL_POINTS)).isEqualTo(true); + } +} \ No newline at end of file diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/data/database/migrations/DataBaseMigrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/data/database/migrations/DataBaseMigrationShould.java index 7cefaece43..9ab920b8a8 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/data/database/migrations/DataBaseMigrationShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/data/database/migrations/DataBaseMigrationShould.java @@ -60,7 +60,7 @@ public class DataBaseMigrationShould { public static final String databaseSqlVersion1 = "db_version_1.sql"; public static final String databaseSqlVersion2_with_data = "db_version_2_with_data.sql"; public static final String databaseSqlVersion2 = "db_version_2.sql"; - public static final String databaseSqlVersion4 = "db_version_4.sql"; + public static final String databaseSqlVersionLast = "db_version_9.sql"; static String dbName= null; private SQLiteDatabase databaseInMemory; @@ -109,7 +109,7 @@ public void have_categoryCombo_columns_after_first_migration() throws IOExceptio @Test public void have_categoryCombo_columns_after_create_version_2_or_newer() throws IOException { - buildD2(initCoreDataBase(dbName, 4, realMigrationDir, databaseSqlVersion4)); + buildD2(initCoreDataBase(dbName, 9, realMigrationDir, databaseSqlVersionLast)); assertVersion2MigrationChanges(d2.databaseAdapter()); } @Test diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/dataelement/DataElementEndpointCallRealIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/dataelement/DataElementEndpointCallRealIntegrationShould.java index 2668ac9d8f..ba4cfdc36a 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/dataelement/DataElementEndpointCallRealIntegrationShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/dataelement/DataElementEndpointCallRealIntegrationShould.java @@ -6,7 +6,6 @@ import org.hisp.dhis.android.core.common.D2Factory; import org.hisp.dhis.android.core.common.GenericCallData; import org.hisp.dhis.android.core.data.database.AbsStoreTestCase; -import org.hisp.dhis.android.core.dataset.DataSetEndpointCall; import org.hisp.dhis.android.core.resource.ResourceHandler; import org.hisp.dhis.android.core.resource.ResourceStoreImpl; import org.junit.Before; @@ -47,7 +46,7 @@ private DataElementEndpointCall createCall() { uids.add("P3jJH5Tu5VC"); uids.add("FQ2o8UBlcrS"); - return DataElementEndpointCall.create(data, uids); + return DataElementEndpointCall.FACTORY.create(data, uids); } // @Test diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/dataset/DataSetAccessEndpointCallRealIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/dataset/DataSetAccessEndpointCallRealIntegrationShould.java new file mode 100644 index 0000000000..6f8645f3f2 --- /dev/null +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/dataset/DataSetAccessEndpointCallRealIntegrationShould.java @@ -0,0 +1,50 @@ +package org.hisp.dhis.android.core.dataset; + +import android.support.test.runner.AndroidJUnit4; + +import org.hisp.dhis.android.core.D2; +import org.hisp.dhis.android.core.common.D2Factory; +import org.hisp.dhis.android.core.common.GenericCallData; +import org.hisp.dhis.android.core.data.database.AbsStoreTestCase; +import org.hisp.dhis.android.core.resource.ResourceHandler; +import org.hisp.dhis.android.core.resource.ResourceStoreImpl; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.io.IOException; + +import static com.google.common.truth.Truth.assertThat; + +@RunWith(AndroidJUnit4.class) +public class DataSetAccessEndpointCallRealIntegrationShould extends AbsStoreTestCase { + private D2 d2; + private DataSetAccessEndpointCall dataSetAccessCall; + + @Before + @Override + public void setUp() throws IOException { + super.setUp(); + d2 = D2Factory.create("https://play.dhis2.org/android-current/api/", databaseAdapter()); + dataSetAccessCall = createCall(); + } + + private DataSetAccessEndpointCall createCall() { + ResourceHandler resourceHandler = + new ResourceHandler(new ResourceStoreImpl(databaseAdapter())); + GenericCallData data = GenericCallData.create(databaseAdapter(), resourceHandler, d2.retrofit()); + + return DataSetAccessEndpointCall.FACTORY.create(data); + } + + @Test + public void download_data_sets() throws Exception { + if (!d2.isUserLoggedIn().call()) { + retrofit2.Response loginResponse = d2.logIn("android", "Android123").call(); + assertThat(loginResponse.isSuccessful()).isTrue(); + } + + retrofit2.Response dataSetResponse = dataSetAccessCall.call(); + assertThat(dataSetResponse.isSuccessful()).isTrue(); + } +} diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/dataset/DataSetEndpointCallRealIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/dataset/DataSetEndpointCallRealIntegrationShould.java index 1be1d7a1e5..cda2161735 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/dataset/DataSetEndpointCallRealIntegrationShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/dataset/DataSetEndpointCallRealIntegrationShould.java @@ -46,13 +46,15 @@ private DataSetEndpointCall createCall() { uids.add("Lpw6GcnTrmS"); uids.add("TuL8IOPzpHh"); - return DataSetEndpointCall.create(data, uids); + return DataSetEndpointCall.FACTORY.create(data, uids); } // @Test public void download_data_sets() throws Exception { - retrofit2.Response loginResponse = d2.logIn("android", "Android123").call(); - assertThat(loginResponse.isSuccessful()).isTrue(); + if (!d2.isUserLoggedIn().call()) { + retrofit2.Response loginResponse = d2.logIn("android", "Android123").call(); + assertThat(loginResponse.isSuccessful()).isTrue(); + } /* This test won't pass independently of DataElementEndpointCall and CategoryComboEndpointCall, as the foreign keys constraints won't be satisfied. diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/dataset/DataSetModelShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/dataset/DataSetModelShould.java index 058f584612..ff51756890 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/dataset/DataSetModelShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/dataset/DataSetModelShould.java @@ -30,10 +30,13 @@ import android.support.test.runner.AndroidJUnit4; +import org.hisp.dhis.android.core.common.Access; +import org.hisp.dhis.android.core.common.DataAccess; import org.hisp.dhis.android.core.common.NameableModelAbstractShould; +import org.hisp.dhis.android.core.common.ObjectStyle; import org.hisp.dhis.android.core.common.ObjectWithUid; -import org.hisp.dhis.android.core.common.PeriodType; import org.hisp.dhis.android.core.dataset.DataSetModel.Columns; +import org.hisp.dhis.android.core.period.PeriodType; import org.hisp.dhis.android.core.utils.ColumnsArrayUtils; import org.hisp.dhis.android.core.utils.Utils; import org.junit.Test; @@ -45,24 +48,26 @@ import static com.google.common.truth.Truth.assertThat; import static org.hisp.dhis.android.core.AndroidTestUtils.toInteger; -import static org.hisp.dhis.android.core.utils.FillPropertiesTestUtils.CODE; -import static org.hisp.dhis.android.core.utils.FillPropertiesTestUtils.CREATED; -import static org.hisp.dhis.android.core.utils.FillPropertiesTestUtils.DELETED; -import static org.hisp.dhis.android.core.utils.FillPropertiesTestUtils.DESCRIPTION; -import static org.hisp.dhis.android.core.utils.FillPropertiesTestUtils.DISPLAY_DESCRIPTION; -import static org.hisp.dhis.android.core.utils.FillPropertiesTestUtils.DISPLAY_NAME; -import static org.hisp.dhis.android.core.utils.FillPropertiesTestUtils.DISPLAY_SHORT_NAME; -import static org.hisp.dhis.android.core.utils.FillPropertiesTestUtils.LAST_UPDATED; -import static org.hisp.dhis.android.core.utils.FillPropertiesTestUtils.NAME; -import static org.hisp.dhis.android.core.utils.FillPropertiesTestUtils.SHORT_NAME; -import static org.hisp.dhis.android.core.utils.FillPropertiesTestUtils.UID; -import static org.hisp.dhis.android.core.utils.FillPropertiesTestUtils.fillNameableModelProperties; +import static org.hisp.dhis.android.core.data.utils.FillPropertiesTestUtils.CODE; +import static org.hisp.dhis.android.core.data.utils.FillPropertiesTestUtils.COLOR; +import static org.hisp.dhis.android.core.data.utils.FillPropertiesTestUtils.CREATED; +import static org.hisp.dhis.android.core.data.utils.FillPropertiesTestUtils.DELETED; +import static org.hisp.dhis.android.core.data.utils.FillPropertiesTestUtils.DESCRIPTION; +import static org.hisp.dhis.android.core.data.utils.FillPropertiesTestUtils.DISPLAY_DESCRIPTION; +import static org.hisp.dhis.android.core.data.utils.FillPropertiesTestUtils.DISPLAY_NAME; +import static org.hisp.dhis.android.core.data.utils.FillPropertiesTestUtils.DISPLAY_SHORT_NAME; +import static org.hisp.dhis.android.core.data.utils.FillPropertiesTestUtils.ICON; +import static org.hisp.dhis.android.core.data.utils.FillPropertiesTestUtils.LAST_UPDATED; +import static org.hisp.dhis.android.core.data.utils.FillPropertiesTestUtils.NAME; +import static org.hisp.dhis.android.core.data.utils.FillPropertiesTestUtils.SHORT_NAME; +import static org.hisp.dhis.android.core.data.utils.FillPropertiesTestUtils.UID; +import static org.hisp.dhis.android.core.data.utils.FillPropertiesTestUtils.fillNameableModelProperties; @RunWith(AndroidJUnit4.class) public class DataSetModelShould extends NameableModelAbstractShould { public DataSetModelShould() { - super(DataSetModel.Columns.all(), 25, DataSetModel.factory); + super(DataSetModel.Columns.all(), 26, DataSetModel.factory); } @Override @@ -84,7 +89,8 @@ protected DataSetModel buildModel() { .skipOffline(false) .dataElementDecoration(false) .renderAsTabs(false) - .renderHorizontally(false); + .renderHorizontally(false) + .accessDataWrite(false); return dataSetModelBuilder.build(); } @@ -96,7 +102,10 @@ protected DataSet buildPojo() { false, 1, 10, 100, false, 0, false, false, false, false, false, - false, false, new ArrayList(), DELETED); + false, false, new ArrayList(), + new ArrayList(), Access.create(true, true, false, true, + true, true, DataAccess.create(true, false)), + ObjectStyle.create(COLOR, ICON), DELETED); } @Override @@ -107,7 +116,8 @@ protected Object[] getModelAsObjectArray() { model.openFuturePeriods(), toInteger(model.fieldCombinationRequired()), toInteger(model.validCompleteOnly()), toInteger(model.noValueRequiresComment()), toInteger(model.skipOffline()), toInteger(model.dataElementDecoration()), - toInteger(model.renderAsTabs()), toInteger(model.renderHorizontally())); + toInteger(model.renderAsTabs()), toInteger(model.renderHorizontally()), + toInteger(model.accessDataWrite())); } @Test @@ -129,5 +139,6 @@ public void have_extra_data_set_model_columns() { assertThat(columnsList.contains(Columns.DATA_ELEMENT_DECORATION)).isEqualTo(true); assertThat(columnsList.contains(Columns.RENDER_AS_TABS)).isEqualTo(true); assertThat(columnsList.contains(Columns.RENDER_HORIZONTALLY)).isEqualTo(true); + assertThat(columnsList.contains(Columns.ACCESS_DATA_WRITE)).isEqualTo(true); } } \ No newline at end of file diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/datavalue/AggregatedDataCallRealIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/datavalue/AggregatedDataCallRealIntegrationShould.java new file mode 100644 index 0000000000..bbbbf0ffc7 --- /dev/null +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/datavalue/AggregatedDataCallRealIntegrationShould.java @@ -0,0 +1,92 @@ +package org.hisp.dhis.android.core.datavalue; + +import org.hisp.dhis.android.core.D2; +import org.hisp.dhis.android.core.common.D2Factory; +import org.hisp.dhis.android.core.data.database.AbsStoreTestCase; +import org.hisp.dhis.android.core.data.server.RealServerMother; +import org.junit.Before; +import org.junit.Test; + +import java.io.IOException; + +import static com.google.common.truth.Truth.assertThat; + +public class AggregatedDataCallRealIntegrationShould extends AbsStoreTestCase { + /** + * A quick integration test that is probably flaky, but will help with finding bugs related to + * the + * metadataSyncCall. It works against the demo server. + */ + private D2 d2; + Exception e; + + @Before + @Override + public void setUp() throws IOException { + super.setUp(); + + d2 = D2Factory.create(RealServerMother.url, databaseAdapter()); + } + + + /* How to extract database from tests: + edit: AbsStoreTestCase.java (adding database name.) + DbOpenHelper dbOpenHelper = new DbOpenHelper(InstrumentationRegistry.getTargetContext() + .getApplicationContext(), "test.db"); + make a debugger break point where desired (after sync complete) + + Then while on the breakpoint : + Android/platform-tools/adb pull /data/user/0/org.hisp.dhis.android.test/databases/test.db + test.db + + in datagrip: + pragma foreign_keys = on; + pragma foreign_key_check;*/ + + //This test is uncommented because technically it is flaky. + //It depends on a live server to operate and the login is hardcoded here. + //Uncomment in order to quickly test changes vs a real server, but keep it uncommented after. + //@Test + public void response_successful_on_sync_data_once() throws Exception { + retrofit2.Response response = null; + d2.logout().call(); + response = d2.logIn("android", "Android123").call(); + assertThat(response.isSuccessful()).isTrue(); + + //first metaData sync: + response = d2.syncMetaData().call(); + assertThat(response.isSuccessful()).isTrue(); + + //first dataValues sync: + response = d2.syncAggregatedData().call(); + assertThat(response.isSuccessful()).isTrue(); + } + + //@Test + public void response_successful_on_sync_data_value_two_times() throws Exception { + retrofit2.Response response = null; + d2.logout().call(); + response = d2.logIn("android", "Android123").call(); + assertThat(response.isSuccessful()).isTrue(); + + //first metaData sync: + response = d2.syncMetaData().call(); + assertThat(response.isSuccessful()).isTrue(); + + //first dataValues sync: + response = d2.syncAggregatedData().call(); + assertThat(response.isSuccessful()).isTrue(); + + //second sync: + response = d2.syncMetaData().call(); + assertThat(response.isSuccessful()).isTrue(); + + //second dataValues sync: + response = d2.syncAggregatedData().call(); + assertThat(response.isSuccessful()).isTrue(); + } + + @Test + public void stub() { + } +} diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/datavalue/DataValueEndpointCallRealIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/datavalue/DataValueEndpointCallRealIntegrationShould.java new file mode 100644 index 0000000000..5b5c151805 --- /dev/null +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/datavalue/DataValueEndpointCallRealIntegrationShould.java @@ -0,0 +1,67 @@ +package org.hisp.dhis.android.core.datavalue; + +import android.support.test.runner.AndroidJUnit4; + +import org.hisp.dhis.android.core.D2; +import org.hisp.dhis.android.core.common.D2Factory; +import org.hisp.dhis.android.core.common.GenericCallData; +import org.hisp.dhis.android.core.data.database.AbsStoreTestCase; +import org.hisp.dhis.android.core.resource.ResourceHandler; +import org.hisp.dhis.android.core.resource.ResourceStoreImpl; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.io.IOException; + +import static com.google.common.truth.Truth.assertThat; +import static org.hisp.dhis.android.core.data.datavalue.DataValueUtils.getDataSetUids; +import static org.hisp.dhis.android.core.data.datavalue.DataValueUtils.getOrgUnitUids; +import static org.hisp.dhis.android.core.data.datavalue.DataValueUtils.getPeriodIds; + +@RunWith(AndroidJUnit4.class) +public class DataValueEndpointCallRealIntegrationShould extends AbsStoreTestCase { + /** + * A quick integration test that is probably flaky, but will help with finding bugs related to the + * metadataSyncCall. It works against the demo server. + */ + private D2 d2; + private DataValueEndpointCall dataValueCall; + + @Before + @Override + public void setUp() throws IOException { + super.setUp(); + d2 = D2Factory.create("https://play.dhis2.org/android-current/api/", databaseAdapter()); + dataValueCall = createCall(); + } + + private DataValueEndpointCall createCall() { + ResourceHandler resourceHandler = + new ResourceHandler(new ResourceStoreImpl(databaseAdapter())); + GenericCallData data = GenericCallData.create(databaseAdapter(), resourceHandler, d2.retrofit()); + + return DataValueEndpointCall.FACTORY.create(data, getDataSetUids(), getPeriodIds(), getOrgUnitUids()); + } + + // @Test + public void download_data_values() throws Exception { + if (!d2.isUserLoggedIn().call()) { + retrofit2.Response loginResponse = d2.logIn("android", "Android123").call(); + assertThat(loginResponse.isSuccessful()).isTrue(); + } + + /* This test won't pass independently of the sync of metadata, as the foreign keys + constraints won't be satisfied. + To run the test, you will need to disable foreign key support in database in + DbOpenHelper.java replacing 'foreign_keys = ON' with 'foreign_keys = OFF' and + uncomment the @Test tag */ + + retrofit2.Response dataValueResponse = dataValueCall.call(); + assertThat(dataValueResponse.isSuccessful()).isTrue(); + } + + @Test + public void stub() { + } +} diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/datavalue/DataValueModelShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/datavalue/DataValueModelShould.java new file mode 100644 index 0000000000..93cf767728 --- /dev/null +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/datavalue/DataValueModelShould.java @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2017, University of Oslo + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.hisp.dhis.android.core.datavalue; + +import android.support.test.runner.AndroidJUnit4; + +import org.hisp.dhis.android.core.common.ModelAbstractShould; +import org.hisp.dhis.android.core.utils.ColumnsArrayUtils; +import org.hisp.dhis.android.core.utils.Utils; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.Arrays; +import java.util.List; + +import static com.google.common.truth.Truth.assertThat; +import static org.hisp.dhis.android.core.AndroidTestUtils.toInteger; +import static org.hisp.dhis.android.core.data.utils.FillPropertiesTestUtils.CREATED; +import static org.hisp.dhis.android.core.data.utils.FillPropertiesTestUtils.CREATED_STR; +import static org.hisp.dhis.android.core.data.utils.FillPropertiesTestUtils.DELETED; +import static org.hisp.dhis.android.core.data.utils.FillPropertiesTestUtils.LAST_UPDATED; +import static org.hisp.dhis.android.core.data.utils.FillPropertiesTestUtils.LAST_UPDATED_STR; + +@RunWith(AndroidJUnit4.class) +public class DataValueModelShould extends ModelAbstractShould { + private static final String DATA_ELEMENT = "dataElement"; + private static final String PERIOD = "period"; + private static final String ORGANISATION_UNIT = "organisationUnit"; + private static final String CATEGORY_OPTION_COMBO = "categoryOptionCombo"; + private static final String ATTRIBUTE_OPTION_COMBO = "attributeOptionCombo"; + private static final String VALUE = "value"; + private static final String STORED_BY = "storedBy"; + private static final String COMMENT = "comment"; + private static final boolean FOLLOW_UP = false; + + public DataValueModelShould() { + super(DataValueModel.Columns.all(), 11, DataValueModel.factory); + } + + @Override + protected DataValue buildPojo() { + return DataValue.create(DATA_ELEMENT, PERIOD, ORGANISATION_UNIT, CATEGORY_OPTION_COMBO, + ATTRIBUTE_OPTION_COMBO, VALUE, STORED_BY, CREATED, LAST_UPDATED, COMMENT, FOLLOW_UP, DELETED); + } + + @Override + protected DataValueModel buildModel() { + DataValueModel.Builder dataValueModelBuilder = DataValueModel.builder(); + dataValueModelBuilder + .dataElement(DATA_ELEMENT) + .period(PERIOD) + .organisationUnit(ORGANISATION_UNIT) + .categoryOptionCombo(CATEGORY_OPTION_COMBO) + .attributeOptionCombo(ATTRIBUTE_OPTION_COMBO) + .value(VALUE) + .storedBy(STORED_BY) + .created(CREATED) + .lastUpdated(LAST_UPDATED) + .comment(COMMENT) + .followUp(FOLLOW_UP); + return dataValueModelBuilder.build(); + } + + @Override + protected Object[] getModelAsObjectArray() { + return Utils.appendInNewArray(ColumnsArrayUtils.getModelAsObjectArray(model), + model.dataElement(), model.period(), model.organisationUnit(), + model.categoryOptionCombo(), model.attributeOptionCombo(), model.value(), + model.storedBy(), CREATED_STR, LAST_UPDATED_STR, model.comment(), + toInteger(model.followUp())); + } + + @Test + public void have_data_value_columns() { + List columnsList = Arrays.asList(DataValueModel.Columns.all()); + + assertThat(columnsList.contains(DataValueModel.Columns.DATA_ELEMENT)).isEqualTo(true); + assertThat(columnsList.contains(DataValueModel.Columns.PERIOD)).isEqualTo(true); + assertThat(columnsList.contains(DataValueModel.Columns.ORGANISATION_UNIT)).isEqualTo(true); + assertThat(columnsList.contains(DataValueModel.Columns.CATEGORY_OPTION_COMBO)).isEqualTo(true); + assertThat(columnsList.contains(DataValueModel.Columns.ATTRIBUTE_OPTION_COMBO)).isEqualTo(true); + assertThat(columnsList.contains(DataValueModel.Columns.VALUE)).isEqualTo(true); + assertThat(columnsList.contains(DataValueModel.Columns.STORED_BY)).isEqualTo(true); + assertThat(columnsList.contains(DataValueModel.Columns.CREATED)).isEqualTo(true); + assertThat(columnsList.contains(DataValueModel.Columns.LAST_UPDATED)).isEqualTo(true); + assertThat(columnsList.contains(DataValueModel.Columns.COMMENT)).isEqualTo(true); + assertThat(columnsList.contains(DataValueModel.Columns.FOLLOW_UP)).isEqualTo(true); + } +} diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/event/EventEndPointCallMockIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/event/EventEndPointCallMockIntegrationShould.java index 80bbfea63d..409344bd9f 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/event/EventEndPointCallMockIntegrationShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/event/EventEndPointCallMockIntegrationShould.java @@ -128,16 +128,7 @@ public void rollback_transaction_when_insert_a_event_with_wrong_foreign_key() } private void givenAMetadataInDatabase() throws Exception { - dhis2MockServer.enqueueMockResponse("system_info.json"); - dhis2MockServer.enqueueMockResponse("user.json"); - dhis2MockServer.enqueueMockResponse("organisationUnits.json"); - dhis2MockServer.enqueueMockResponse("categories.json"); - dhis2MockServer.enqueueMockResponse("category_combos.json"); - dhis2MockServer.enqueueMockResponse("programs.json"); - dhis2MockServer.enqueueMockResponse("tracked_entities.json"); - dhis2MockServer.enqueueMockResponse("option_sets.json"); - dhis2MockServer.enqueueMockResponse("data_sets.json"); - dhis2MockServer.enqueueMockResponse("data_elements.json"); + dhis2MockServer.enqueueMetadataResponses(); d2.syncMetaData().call(); } diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/indicator/DataSetIndicatorLinkModelShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/indicator/DataSetIndicatorLinkModelShould.java new file mode 100644 index 0000000000..a42bfec46a --- /dev/null +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/indicator/DataSetIndicatorLinkModelShould.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2017, University of Oslo + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.hisp.dhis.android.core.indicator; + +import android.support.test.runner.AndroidJUnit4; + +import org.hisp.dhis.android.core.common.LinkModelAbstractShould; +import org.hisp.dhis.android.core.indicator.DataSetIndicatorLinkModel.Columns; +import org.hisp.dhis.android.core.utils.ColumnsArrayUtils; +import org.hisp.dhis.android.core.utils.Utils; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.Arrays; +import java.util.List; + +import static com.google.common.truth.Truth.assertThat; + +@RunWith(AndroidJUnit4.class) +public class DataSetIndicatorLinkModelShould extends + LinkModelAbstractShould { + + public DataSetIndicatorLinkModelShould() { + super(Columns.all(), 2, DataSetIndicatorLinkModel.factory); + } + + @Override + protected DataSetIndicatorLinkModel buildModel() { + return DataSetIndicatorLinkModel.create("data_set_uid", + "indicator_uid"); + } + + @Override + protected Object[] getModelAsObjectArray() { + return Utils.appendInNewArray(ColumnsArrayUtils.getModelAsObjectArray(model), + model.dataSet(), model.indicator()); + } + + @Test + public void have_data_set_indicator_model_columns() { + List columnsList = Arrays.asList(Columns.all()); + + assertThat(columnsList.contains(Columns.DATA_SET)).isEqualTo(true); + assertThat(columnsList.contains(Columns.INDICATOR)).isEqualTo(true); + } +} \ No newline at end of file diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/indicator/IndicatorModelShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/indicator/IndicatorModelShould.java new file mode 100644 index 0000000000..c59b345c5d --- /dev/null +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/indicator/IndicatorModelShould.java @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2017, University of Oslo + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.hisp.dhis.android.core.indicator; + +import android.support.test.runner.AndroidJUnit4; + +import org.hisp.dhis.android.core.common.NameableModelAbstractShould; +import org.hisp.dhis.android.core.common.ObjectWithUid; +import org.hisp.dhis.android.core.indicator.IndicatorModel.Columns; +import org.hisp.dhis.android.core.utils.ColumnsArrayUtils; +import org.hisp.dhis.android.core.utils.Utils; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.Arrays; +import java.util.List; + +import static com.google.common.truth.Truth.assertThat; +import static org.hisp.dhis.android.core.data.utils.FillPropertiesTestUtils.CODE; +import static org.hisp.dhis.android.core.data.utils.FillPropertiesTestUtils.CREATED; +import static org.hisp.dhis.android.core.data.utils.FillPropertiesTestUtils.DELETED; +import static org.hisp.dhis.android.core.data.utils.FillPropertiesTestUtils.DESCRIPTION; +import static org.hisp.dhis.android.core.data.utils.FillPropertiesTestUtils.DISPLAY_DESCRIPTION; +import static org.hisp.dhis.android.core.data.utils.FillPropertiesTestUtils.DISPLAY_NAME; +import static org.hisp.dhis.android.core.data.utils.FillPropertiesTestUtils.DISPLAY_SHORT_NAME; +import static org.hisp.dhis.android.core.data.utils.FillPropertiesTestUtils.LAST_UPDATED; +import static org.hisp.dhis.android.core.data.utils.FillPropertiesTestUtils.NAME; +import static org.hisp.dhis.android.core.data.utils.FillPropertiesTestUtils.SHORT_NAME; +import static org.hisp.dhis.android.core.data.utils.FillPropertiesTestUtils.UID; +import static org.hisp.dhis.android.core.data.utils.FillPropertiesTestUtils.fillNameableModelProperties; + +@RunWith(AndroidJUnit4.class) +public class IndicatorModelShould extends NameableModelAbstractShould { + + private final Boolean annualized = false; + private final String indicatorType = "bWuNrMHEoZ0"; + private final String numerator = "#{a.b}"; + private final String numeratorDescription = "num descr"; + private final String denominator = "#{c.d}"; + private final String denominatorDescription = "den descr"; + private final String url = "dhis2.org"; + + public IndicatorModelShould() { + super(IndicatorModel.Columns.all(), 17, IndicatorModel.factory); + } + + @Override + protected IndicatorModel buildModel() { + IndicatorModel.Builder indicatorModelBuilder = IndicatorModel.builder(); + fillNameableModelProperties(indicatorModelBuilder); + indicatorModelBuilder + .annualized(annualized) + .indicatorType(indicatorType) + .numerator(numerator) + .numeratorDescription(numeratorDescription) + .denominator(denominator) + .denominatorDescription(denominatorDescription) + .url(url); + return indicatorModelBuilder.build(); + } + + @Override + protected Indicator buildPojo() { + return Indicator.create(UID, CODE, NAME, DISPLAY_NAME, CREATED, LAST_UPDATED, SHORT_NAME, + DISPLAY_SHORT_NAME, DESCRIPTION, DISPLAY_DESCRIPTION, annualized, + ObjectWithUid.create(indicatorType), numerator, numeratorDescription, + denominator, denominatorDescription, url, DELETED); + } + + @Override + protected Object[] getModelAsObjectArray() { + return Utils.appendInNewArray(ColumnsArrayUtils.getNameableModelAsObjectArray(model), + model.annualized(), model.indicatorType(), model.numerator(), + model.numeratorDescription(), model.denominator(), model.denominatorDescription(), + model.url()); + } + + @Test + public void have_extra_indicator_model_columns() { + List columnsList = Arrays.asList(columns); + + assertThat(columnsList.contains(Columns.ANNUALIZED)).isEqualTo(true); + assertThat(columnsList.contains(Columns.INDICATOR_TYPE)).isEqualTo(true); + assertThat(columnsList.contains(Columns.NUMERATOR)).isEqualTo(true); + assertThat(columnsList.contains(Columns.NUMERATOR_DESCRIPTION)).isEqualTo(true); + assertThat(columnsList.contains(Columns.DENOMINATOR)).isEqualTo(true); + assertThat(columnsList.contains(Columns.DENOMINATOR_DESCRIPTION)).isEqualTo(true); + assertThat(columnsList.contains(Columns.URL)).isEqualTo(true); + } +} \ No newline at end of file diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/indicator/IndicatorTypeModelShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/indicator/IndicatorTypeModelShould.java new file mode 100644 index 0000000000..f4f3308168 --- /dev/null +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/indicator/IndicatorTypeModelShould.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2017, University of Oslo + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.hisp.dhis.android.core.indicator; + +import android.support.test.runner.AndroidJUnit4; + +import org.hisp.dhis.android.core.common.IdentifiableModelAbstractShould; +import org.hisp.dhis.android.core.indicator.IndicatorTypeModel.Columns; +import org.hisp.dhis.android.core.utils.ColumnsArrayUtils; +import org.hisp.dhis.android.core.utils.Utils; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.Arrays; +import java.util.List; + +import static com.google.common.truth.Truth.assertThat; +import static org.hisp.dhis.android.core.data.utils.FillPropertiesTestUtils.CODE; +import static org.hisp.dhis.android.core.data.utils.FillPropertiesTestUtils.CREATED; +import static org.hisp.dhis.android.core.data.utils.FillPropertiesTestUtils.DELETED; +import static org.hisp.dhis.android.core.data.utils.FillPropertiesTestUtils.DISPLAY_NAME; +import static org.hisp.dhis.android.core.data.utils.FillPropertiesTestUtils.LAST_UPDATED; +import static org.hisp.dhis.android.core.data.utils.FillPropertiesTestUtils.NAME; +import static org.hisp.dhis.android.core.data.utils.FillPropertiesTestUtils.UID; +import static org.hisp.dhis.android.core.data.utils.FillPropertiesTestUtils.fillIdentifiableModelProperties; + +@RunWith(AndroidJUnit4.class) +public class IndicatorTypeModelShould extends IdentifiableModelAbstractShould { + + private final Boolean number = false; + private final Integer factor = 100; + + public IndicatorTypeModelShould() { + super(Columns.all(), 8, IndicatorTypeModel.factory); + } + + @Override + protected IndicatorTypeModel buildModel() { + IndicatorTypeModel.Builder builder = IndicatorTypeModel.builder(); + fillIdentifiableModelProperties(builder); + builder + .number(number) + .factor(factor); + return builder.build(); + } + + @Override + protected IndicatorType buildPojo() { + return IndicatorType.create(UID, CODE, NAME, DISPLAY_NAME, CREATED, LAST_UPDATED, + number, factor, DELETED); + } + + @Override + protected Object[] getModelAsObjectArray() { + return Utils.appendInNewArray(ColumnsArrayUtils.getIdentifiableModelAsObjectArray(model), + model.number(), model.factor()); + } + + @Test + public void have_extra_indicator_model_columns() { + List columnsList = Arrays.asList(columns); + + assertThat(columnsList.contains(Columns.NUMBER)).isEqualTo(true); + assertThat(columnsList.contains(Columns.FACTOR)).isEqualTo(true); + } +} \ No newline at end of file diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/option/OptionSetCallShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/option/OptionSetCallShould.java index 33f2e2b65b..3c63e4b708 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/option/OptionSetCallShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/option/OptionSetCallShould.java @@ -215,7 +215,7 @@ public void setUp() throws IOException { GenericCallData data = GenericCallData.create(databaseAdapter(), new ResourceHandler(resourceStore), retrofit); - GenericHandler optionSetHandler = OptionSetHandler.create(databaseAdapter()); + GenericHandler optionSetHandler = OptionSetHandler.create(databaseAdapter()); optionSetCall = new OptionSetCall(data, optionSetService, optionSetHandler, uids); diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/option/OptionSetStoreShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/option/OptionSetStoreShould.java deleted file mode 100644 index d4af220fea..0000000000 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/option/OptionSetStoreShould.java +++ /dev/null @@ -1,279 +0,0 @@ -/* - * Copyright (c) 2017, University of Oslo - * - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * Neither the name of the HISP project nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - *//* - - -package org.hisp.dhis.android.core.option; - -import android.content.ContentValues; -import android.database.Cursor; - -import org.hisp.dhis.android.core.common.BaseIdentifiableObject; -import org.hisp.dhis.android.core.common.ValueType; -import org.hisp.dhis.android.core.data.database.AbsStoreTestCase; -import org.hisp.dhis.android.core.option.OptionSetModel.Columns; -import org.junit.Before; -import org.junit.Test; - -import java.io.IOException; -import java.text.ParseException; -import java.util.Date; - -import static com.google.common.truth.Truth.assertThat; -import static org.hisp.dhis.android.core.data.database.CursorAssert.assertThatCursor; - -public class OptionSetStoreShould extends AbsStoreTestCase { - - private static final String UID = "test_uid"; - private static final String CODE = "test_code"; - private static final String NAME = "test_name"; - private static final String DISPLAY_NAME = "test_display_name"; - private static final ValueType VALUE_TYPE = ValueType.BOOLEAN; - private static final int VERSION = 51; - - // timestamp - private static final String DATE = "2016-12-20T16:26:00.007"; - private final Date date; - - private static final String[] OPTION_SET_PROJECTION = { - Columns.UID, Columns.CODE, Columns.NAME, - Columns.DISPLAY_NAME, Columns.CREATED, - Columns.LAST_UPDATED, Columns.VERSION, Columns.VALUE_TYPE - }; - - private OptionSetStore store; - - public OptionSetStoreShould() throws ParseException { - this.date = BaseIdentifiableObject.DATE_FORMAT.parse(DATE); - } - - @Before - @Override - public void setUp() throws IOException { - super.setUp(); - this.store = new OptionSetStoreImpl(databaseAdapter()); - } - - @Test - public void should_persist_option_set_in_data_base_when_persist() throws ParseException { - long rowId = store.insert( - UID, CODE, NAME, DISPLAY_NAME, date, date, VERSION, VALUE_TYPE); - - Cursor cursor = database().query(OptionSetModel.TABLE, OPTION_SET_PROJECTION, - null, null, null, null, null); - - // Checking if rowId == 1. - // If it is 1, then it means it is first successful insert into db - assertThat(rowId).isEqualTo(1L); - assertThatCursor(cursor).hasRow( - UID, CODE, NAME, - DISPLAY_NAME, BaseIdentifiableObject.DATE_FORMAT.format(date), - BaseIdentifiableObject.DATE_FORMAT.format(date), - VERSION, VALUE_TYPE).isExhausted(); - } - - @Test - public void update_option_set_in_data_base_when_update() throws Exception { - ContentValues optionSet = new ContentValues(); - optionSet.put(Columns.ID, 1L); - optionSet.put(Columns.UID, UID); - optionSet.put(Columns.VERSION, VERSION); - optionSet.put(Columns.NAME, NAME); - optionSet.put(Columns.DISPLAY_NAME, DISPLAY_NAME); - - database().insert(OptionSetModel.TABLE, null, optionSet); - - String[] projection = {Columns.UID, Columns.NAME, Columns.DISPLAY_NAME}; - Cursor cursor = database().query(OptionSetModel.TABLE, projection, null, null, null, null, null); - - // checking that option set is successfully inserted - assertThatCursor(cursor).hasRow(UID, NAME, DISPLAY_NAME).isExhausted(); - - int updatedRow = store.update( - UID, CODE, "new_name", "new_display_name", date, date, 5, VALUE_TYPE, UID - ); - - assertThat(updatedRow).isEqualTo(1); - - cursor = database().query(OptionSetModel.TABLE, projection, null, null, null, null, null); - - assertThatCursor(cursor).hasRow( - UID, "new_name", "new_display_name" - ).isExhausted(); - - } - - @Test - public void delete_option_set_in_data_base_when_delete() throws Exception { - ContentValues optionSet = new ContentValues(); - optionSet.put(Columns.ID, 1L); - optionSet.put(Columns.UID, UID); - optionSet.put(Columns.NAME, NAME); - optionSet.put(Columns.DISPLAY_NAME, DISPLAY_NAME); - - database().insert(OptionSetModel.TABLE, null, optionSet); - - String[] projection = {Columns.UID, Columns.NAME, Columns.DISPLAY_NAME}; - Cursor cursor = database().query(OptionSetModel.TABLE, projection, null, null, null, null, null); - - // checking that option set is successfully inserted - assertThatCursor(cursor).hasRow(UID, NAME, DISPLAY_NAME).isExhausted(); - - // deleting the optionSet - store.delete(UID); - - cursor = database().query(OptionSetModel.TABLE, projection, null, null, null, null, null); - - // checking that optionSet is deleted - assertThatCursor(cursor).isExhausted(); - } - - @Test - public void delete_an_updated_option_set_in_data_base_when_delete() throws Exception { - ContentValues optionSet = new ContentValues(); - optionSet.put(Columns.ID, 1L); - optionSet.put(Columns.UID, UID); - optionSet.put(Columns.NAME, NAME); - optionSet.put(Columns.DISPLAY_NAME, DISPLAY_NAME); - - database().insert(OptionSetModel.TABLE, null, optionSet); - - String[] projection = {Columns.UID, Columns.NAME, Columns.DISPLAY_NAME}; - Cursor cursor = database().query(OptionSetModel.TABLE, projection, null, null, null, null, null); - - // checking that option set is successfully inserted - assertThatCursor(cursor).hasRow(UID, NAME, DISPLAY_NAME).isExhausted(); - - // updates the option set with new uid - store.update( - "new_uid", CODE, NAME, DISPLAY_NAME, date, date, 5, VALUE_TYPE, UID - ); - - cursor = database().query(OptionSetModel.TABLE, projection, null, null, null, null, null); - - // checking that optionSet was successfully updated - assertThatCursor(cursor).hasRow("new_uid", NAME, DISPLAY_NAME).isExhausted(); - - // deletes the option set - store.delete("new_uid"); - - cursor = database().query(OptionSetModel.TABLE, projection, null, null, null, null, null); - - // checking that the option set was successfully deleted - assertThatCursor(cursor).isExhausted(); - - } - - @Test(expected = IllegalArgumentException.class) - public void throw_illegal_argument_exception_after_insert_null_uid() { - store.insert(null, CODE, NAME, DISPLAY_NAME, date, date, VERSION, VALUE_TYPE); - } - - @Test(expected = IllegalArgumentException.class) - public void throw_illegal_argument_exception_after_update_null_uid() { - store.update(null, CODE, NAME, DISPLAY_NAME, date, date, VERSION, VALUE_TYPE, UID); - } - - @Test(expected = IllegalArgumentException.class) - public void throw_illegal_argument_exception_after_update_null_whereUid() { - store.update(UID, CODE, NAME, DISPLAY_NAME, date, date, VERSION, VALUE_TYPE, null); - } - - @Test(expected = IllegalArgumentException.class) - public void throw_illegal_argument_exception_after_delete_null_uid() { - store.delete(null); - } - - // @Test -// public void persist_option_set_in_data_base_after_insert_or_replace() throws ParseException { -// database().beginTransaction(); -// Date date = BaseIdentifiableObject.DATE_FORMAT.parse(DATE); -// -// ContentValues optionSet = new ContentValues(); -// optionSet.put(Columns.ID, 1L); -// optionSet.put(Columns.UID, UID); -// optionSet.put(Columns.VERSION, VERSION); -// optionSet.put(Columns.NAME, NAME); -// optionSet.put(Columns.DISPLAY_NAME, DISPLAY_NAME); -// -// database().insert(OptionSetModel.TABLE, null, optionSet); -// -// String[] projection = {Columns.UID, Columns.NAME, Columns.DISPLAY_NAME}; -// Cursor cursor = database().query(OptionSetModel.TABLE, projection, null, null, null, null, null); -// -// // checking that option set is successfully inserted -// assertThatCursor(cursor).hasRow(UID, NAME, DISPLAY_NAME).isExhausted(); -// -// -// // inserting two options linked to the option set -// String optionUid = "option_uid"; -// ContentValues option = new ContentValues(); -// option.put(OptionModel.Columns.ID, 1L); -// option.put(OptionModel.Columns.UID, optionUid); -// option.put(OptionModel.Columns.OPTION_SET, UID); -// -// database().insert(OptionModel.TABLE, null, option); -// -// String option1Uid = "option1_uid"; -// ContentValues option1 = new ContentValues(); -// option1.put(OptionModel.Columns.ID, 2L); -// option1.put(OptionModel.Columns.UID, option1Uid); -// option1.put(OptionModel.Columns.OPTION_SET, UID); -// -// database().insert(OptionModel.TABLE, null, option1); -// -// String[] optionProjection = {OptionModel.Columns.UID, OptionModel.Columns.OPTION_SET}; -// -// cursor = database().query(OptionModel.TABLE, optionProjection, null, null, null, null, null); -// -// assertThatCursor(cursor).hasRow(optionUid, UID); -// assertThatCursor(cursor).hasRow(option1Uid, UID).isExhausted(); -// -// String newOptionSetName = "newOptionSetName"; -// String newOptionSetDisplayName = "newOptionSetDisplayName"; -// -// store.insertOrReplace(UID, CODE, newOptionSetName, newOptionSetDisplayName, date, date, VERSION, -// VALUE_TYPE); -// -// cursor = database().query(OptionSetModel.TABLE, projection, null, null, null, null, null); -// -// assertThatCursor(cursor).hasRow(UID, newOptionSetName, newOptionSetDisplayName).isExhausted(); -// -// -// cursor = database().query(OptionModel.TABLE, optionProjection, null, null, null, null, null); -// -// assertThatCursor(cursor).hasRow(optionUid, UID); -// assertThatCursor(cursor).hasRow(option1Uid, UID).isExhausted(); -// -// database().setTransactionSuccessful(); -// -// database().endTransaction(); -// -// } - -} -*/ diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/organisationunit/OrganisationUnitCallMockIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/organisationunit/OrganisationUnitCallMockIntegrationShould.java index 16e32e8746..48935a9694 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/organisationunit/OrganisationUnitCallMockIntegrationShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/organisationunit/OrganisationUnitCallMockIntegrationShould.java @@ -33,14 +33,15 @@ import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; -import org.hisp.dhis.android.core.common.BaseIdentifiableObject; import org.hisp.dhis.android.core.calls.Call; +import org.hisp.dhis.android.core.common.BaseIdentifiableObject; import org.hisp.dhis.android.core.common.Payload; import org.hisp.dhis.android.core.data.api.FieldsConverterFactory; import org.hisp.dhis.android.core.data.database.AbsStoreTestCase; import org.hisp.dhis.android.core.program.ProgramModel; -import org.hisp.dhis.android.core.resource.ResourceModel; import org.hisp.dhis.android.core.resource.ResourceStore; import org.hisp.dhis.android.core.resource.ResourceStoreImpl; import org.hisp.dhis.android.core.user.User; @@ -59,6 +60,7 @@ import java.util.Collections; import java.util.Date; import java.util.List; +import java.util.Set; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; @@ -288,45 +290,59 @@ public void setUp() throws IOException { database().insert(UserModel.TABLE, null, userContentValues); // inserting programs for creating OrgUnitProgramLinks + + String programUid = "uy2gU8kT1jF"; + String programUid1 = "q04UBOqq3rp"; + String programUid2 = "VBqh0ynB2wv"; + String programUid3 = "eBAyeGv0exc"; + String programUid4 = "kla3mAPgvCH"; + String programUid5 = "lxAQ7Zs9VYR"; + String programUid6 = "IpHINAT79UW"; + String programUid7 = "WSGAb5XwJ3Y"; + String programUid8 = "ur1Edk5Oe2n"; + ContentValues program = new ContentValues(); - program.put(ProgramModel.Columns.UID, "uy2gU8kT1jF"); + program.put(ProgramModel.Columns.UID, programUid); database().insert(ProgramModel.TABLE, null, program); ContentValues program1 = new ContentValues(); - program1.put(ProgramModel.Columns.UID, "q04UBOqq3rp"); + program1.put(ProgramModel.Columns.UID, programUid1); database().insert(ProgramModel.TABLE, null, program1); ContentValues program2 = new ContentValues(); - program2.put(ProgramModel.Columns.UID, "VBqh0ynB2wv"); + program2.put(ProgramModel.Columns.UID, programUid2); database().insert(ProgramModel.TABLE, null, program2); ContentValues program3 = new ContentValues(); - program3.put(ProgramModel.Columns.UID, "eBAyeGv0exc"); + program3.put(ProgramModel.Columns.UID, programUid3); database().insert(ProgramModel.TABLE, null, program3); ContentValues program4 = new ContentValues(); - program4.put(ProgramModel.Columns.UID, "kla3mAPgvCH"); + program4.put(ProgramModel.Columns.UID, programUid4); database().insert(ProgramModel.TABLE, null, program4); ContentValues program5 = new ContentValues(); - program5.put(ProgramModel.Columns.UID, "lxAQ7Zs9VYR"); + program5.put(ProgramModel.Columns.UID, programUid5); database().insert(ProgramModel.TABLE, null, program5); ContentValues program6 = new ContentValues(); - program6.put(ProgramModel.Columns.UID, "IpHINAT79UW"); + program6.put(ProgramModel.Columns.UID, programUid6); database().insert(ProgramModel.TABLE, null, program6); ContentValues program7 = new ContentValues(); - program7.put(ProgramModel.Columns.UID, "WSGAb5XwJ3Y"); + program7.put(ProgramModel.Columns.UID, programUid7); database().insert(ProgramModel.TABLE, null, program7); ContentValues program8 = new ContentValues(); - program8.put(ProgramModel.Columns.UID, "ur1Edk5Oe2n"); + program8.put(ProgramModel.Columns.UID, programUid8); database().insert(ProgramModel.TABLE, null, program8); + Set programUids = Sets.newHashSet(Lists.newArrayList(programUid, programUid1, programUid2, + programUid3, programUid4, programUid5, programUid6, programUid7, programUid8)); + organisationUnitCall = new OrganisationUnitCall(user, organisationUnitService, databaseAdapter(), organisationUnitStore, resourceStore, new Date(), userOrganisationUnitLinkStore, - organisationUnitProgramLinkStore); + organisationUnitProgramLinkStore, programUids); } @Test diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/user/UserRoleProgramLinkModelShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/period/PeriodModelShould.java similarity index 58% rename from core/src/androidTest/java/org/hisp/dhis/android/core/user/UserRoleProgramLinkModelShould.java rename to core/src/androidTest/java/org/hisp/dhis/android/core/period/PeriodModelShould.java index a56689fe6c..52c2e0e05e 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/user/UserRoleProgramLinkModelShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/period/PeriodModelShould.java @@ -25,49 +25,49 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package org.hisp.dhis.android.core.user; -import android.content.ContentValues; +package org.hisp.dhis.android.core.period; + import android.database.MatrixCursor; import android.support.test.runner.AndroidJUnit4; -import org.hisp.dhis.android.core.user.UserRoleProgramLinkModel.Columns; +import org.hisp.dhis.android.core.common.BaseIdentifiableObject; import org.junit.Test; import org.junit.runner.RunWith; +import java.text.ParseException; +import java.util.Date; + import static com.google.common.truth.Truth.assertThat; @RunWith(AndroidJUnit4.class) -public class UserRoleProgramLinkModelShould { - private static final long ID = 1L; - private static final String USER_ROLE = "test_user_role_uid"; - private static final String PROGRAM = "test_program_uid"; +public class PeriodModelShould { @Test - public void create_model_when_created_from_database_cursor() { - MatrixCursor cursor = new MatrixCursor(new String[]{Columns.ID, Columns.USER_ROLE, Columns.PROGRAM}); - cursor.addRow(new Object[]{ID, USER_ROLE, PROGRAM}); - cursor.moveToFirst(); + public void create_model_when_created_from_database_cursor() throws ParseException { + String periodId = "2018W1"; + String periodType = PeriodType.Weekly.toString(); - UserRoleProgramLinkModel model = UserRoleProgramLinkModel.create(cursor); - cursor.close(); + String startDateStr = "2018-01-01T00:00:00.000"; + Date startDate = BaseIdentifiableObject.DATE_FORMAT.parse(startDateStr); + String endDateStr = "2018-01-07T23:59:59.999"; + Date endDate = BaseIdentifiableObject.DATE_FORMAT.parse(endDateStr); - assertThat(model.id()).isEqualTo(ID); - assertThat(model.userRole()).isEqualTo(USER_ROLE); - assertThat(model.program()).isEqualTo(PROGRAM); - } + MatrixCursor cursor = new MatrixCursor(PeriodModel.Columns.all()); + cursor.addRow(new Object[]{ + periodId, + periodType, + startDateStr, + endDateStr + }); + cursor.moveToFirst(); - @Test - public void create_content_values_when_created_from_builder() { - UserRoleProgramLinkModel model = UserRoleProgramLinkModel.builder() - .id(ID) - .userRole(USER_ROLE) - .program(PROGRAM) - .build(); - ContentValues contentValues = model.toContentValues(); + PeriodModel model = PeriodModel.create(cursor); + cursor.close(); - assertThat(contentValues.getAsLong(Columns.ID)).isEqualTo(ID); - assertThat(contentValues.getAsString(Columns.USER_ROLE)).isEqualTo(USER_ROLE); - assertThat(contentValues.getAsString(Columns.PROGRAM)).isEqualTo(PROGRAM); + assertThat(model.periodId()).isEqualTo(periodId); + assertThat(model.periodType()).isEqualTo(PeriodType.Weekly); + assertThat(model.startDate()).isEqualTo(startDate); + assertThat(model.endDate()).isEqualTo(endDate); } -} +} \ No newline at end of file diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/program/ProgramAccessEndpointCallRealIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/program/ProgramAccessEndpointCallRealIntegrationShould.java new file mode 100644 index 0000000000..977bd96628 --- /dev/null +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/program/ProgramAccessEndpointCallRealIntegrationShould.java @@ -0,0 +1,51 @@ +package org.hisp.dhis.android.core.program; + +import android.support.test.runner.AndroidJUnit4; + +import org.hisp.dhis.android.core.D2; +import org.hisp.dhis.android.core.common.D2Factory; +import org.hisp.dhis.android.core.common.GenericCallData; +import org.hisp.dhis.android.core.data.database.AbsStoreTestCase; +import org.hisp.dhis.android.core.resource.ResourceHandler; +import org.hisp.dhis.android.core.resource.ResourceStoreImpl; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.io.IOException; + +import static com.google.common.truth.Truth.assertThat; + +@RunWith(AndroidJUnit4.class) +public class ProgramAccessEndpointCallRealIntegrationShould extends AbsStoreTestCase { + private D2 d2; + private ProgramAccessEndpointCall programAccessCall; + + @Before + @Override + public void setUp() throws IOException { + super.setUp(); + d2 = D2Factory.create("https://play.dhis2.org/android-current/api/", databaseAdapter()); + programAccessCall = createCall(); + } + + private ProgramAccessEndpointCall createCall() { + ResourceHandler resourceHandler = + new ResourceHandler(new ResourceStoreImpl(databaseAdapter())); + GenericCallData data = GenericCallData.create(databaseAdapter(), resourceHandler, d2.retrofit()); + ProgramService service = d2.retrofit().create(ProgramService.class); + + return ProgramAccessEndpointCall.FACTORY.create(data, service); + } + + @Test + public void download_programs() throws Exception { + if (!d2.isUserLoggedIn().call()) { + retrofit2.Response loginResponse = d2.logIn("android", "Android123").call(); + assertThat(loginResponse.isSuccessful()).isTrue(); + } + + retrofit2.Response programResponse = programAccessCall.call(); + assertThat(programResponse.isSuccessful()).isTrue(); + } +} diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/program/ProgramCallMockIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/program/ProgramCallMockIntegrationShould.java index b888342e06..9f88ba7f0f 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/program/ProgramCallMockIntegrationShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/program/ProgramCallMockIntegrationShould.java @@ -41,7 +41,12 @@ import org.hisp.dhis.android.core.common.BaseIdentifiableObject; import org.hisp.dhis.android.core.common.D2Factory; import org.hisp.dhis.android.core.common.GenericHandler; +import org.hisp.dhis.android.core.common.DictionaryTableHandler; +import org.hisp.dhis.android.core.common.ObjectStyle; +import org.hisp.dhis.android.core.common.ObjectStyleHandler; import org.hisp.dhis.android.core.common.Payload; +import org.hisp.dhis.android.core.common.ValueTypeRendering; +import org.hisp.dhis.android.core.common.ValueTypeRenderingHandler; import org.hisp.dhis.android.core.data.database.AbsStoreTestCase; import org.hisp.dhis.android.core.data.file.AssetsFileReader; import org.hisp.dhis.android.core.data.server.Dhis2MockServer; @@ -110,7 +115,8 @@ public class ProgramCallMockIntegrationShould extends AbsStoreTestCase { ProgramModel.Columns.RELATIONSHIP_TEXT, ProgramModel.Columns.RELATED_PROGRAM, ProgramModel.Columns.TRACKED_ENTITY, - ProgramModel.Columns.CATEGORY_COMBO + ProgramModel.Columns.CATEGORY_COMBO, + ProgramModel.Columns.ACCESS_DATA_WRITE }; private Dhis2MockServer dhis2MockServer; @@ -133,8 +139,11 @@ public void setUp() throws IOException { TrackedEntityAttributeStore trackedEntityAttributeStore = new TrackedEntityAttributeStoreImpl(databaseAdapter()); + TrackedEntityAttributeHandler trackedEntityAttributeHandler = - new TrackedEntityAttributeHandler(trackedEntityAttributeStore); + new TrackedEntityAttributeHandler(trackedEntityAttributeStore, + ObjectStyleHandler.create(databaseAdapter()), + ValueTypeRenderingHandler.create(databaseAdapter())); ProgramTrackedEntityAttributeStore programTrackedEntityAttributeStore = new ProgramTrackedEntityAttributeStoreImpl(databaseAdapter()); @@ -163,9 +172,8 @@ public void setUp() throws IOException { ProgramRuleStore programRuleStore = new ProgramRuleStoreImpl(databaseAdapter()); ProgramRuleHandler programRuleHandler = new ProgramRuleHandler(programRuleStore, programRuleActionHandler); - GenericHandler optionSetHandler = - OptionSetHandler.create(databaseAdapter()); - GenericHandler dataElementHandler = + GenericHandler optionSetHandler = OptionSetHandler.create(databaseAdapter()); + GenericHandler dataElementHandler = DataElementHandler.create(databaseAdapter(), optionSetHandler); ProgramStageDataElementStore programStageDataElementStore = new ProgramStageDataElementStoreImpl(databaseAdapter()); @@ -181,12 +189,16 @@ public void setUp() throws IOException { programIndicatorHandler ); + DictionaryTableHandler styleHandler = ObjectStyleHandler.create(databaseAdapter()); + DictionaryTableHandler renderTypeHandler + = ValueTypeRenderingHandler.create(databaseAdapter()); + ProgramStageStore programStageStore = new ProgramStageStoreImpl(databaseAdapter()); ProgramStageHandler programStageHandler = new ProgramStageHandler( programStageStore, programStageSectionHandler, - programStageDataElementHandler - ); + programStageDataElementHandler, + styleHandler); RelationshipTypeStore relationshipStore = new RelationshipTypeStoreImpl(databaseAdapter()); RelationshipTypeHandler relationshipTypeHandler = new RelationshipTypeHandler(relationshipStore); @@ -201,7 +213,8 @@ public void setUp() throws IOException { programIndicatorHandler, programRuleHandler, programTrackedEntityAttributeHandler, - relationshipTypeHandler); + relationshipTypeHandler, + styleHandler); ResourceStore resourceStore = new ResourceStoreImpl(databaseAdapter()); ResourceHandler resourceHandler = new ResourceHandler(resourceStore); @@ -225,7 +238,8 @@ programService, databaseAdapter(), resourceStore, uids, programStore, new Date() trackedEntityAttributeStore, programTrackedEntityAttributeStore, programRuleVariableStore, programIndicatorStore, programStageSectionProgramIndicatorLinkStore, programRuleActionStore, programRuleStore, programStageDataElementStore, - programStageSectionStore, programStageStore, relationshipStore, dataElementHandler + programStageSectionStore, programStageStore, relationshipStore, dataElementHandler, + styleHandler, renderTypeHandler ); } @@ -266,7 +280,8 @@ public void persist_program_when_call() throws Exception { null, null, "nEenWmSyUEp", - "nM3u9s5a52V" + "nM3u9s5a52V", + 0 ).isExhausted(); } @@ -345,11 +360,26 @@ public void not_persist_program_stage_sections_when_call() throws Exception { ProgramStageSectionModel.Columns.CREATED, ProgramStageSectionModel.Columns.LAST_UPDATED, ProgramStageSectionModel.Columns.SORT_ORDER, - ProgramStageSectionModel.Columns.PROGRAM_STAGE + ProgramStageSectionModel.Columns.PROGRAM_STAGE, + ProgramStageSectionModel.Columns.DESKTOP_RENDER_TYPE, + ProgramStageSectionModel.Columns.MOBILE_RENDER_TYPE }; Cursor programStageSectionCursor = database().query(ProgramStageSectionModel.TABLE, projection, null, null, null, null, null); + assertThatCursor(programStageSectionCursor).hasRow( + "OeSqs7pkKqI", + null, + null, + null, + null, + null, + null, + "A03MvHHogjR", + ProgramStageSectionRenderingType.SEQUENTIAL.toString(), + ProgramStageSectionRenderingType.MATRIX.toString() + ).isExhausted(); + assertThatCursor(programStageSectionCursor).isExhausted(); } diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/program/ProgramStageSectionModelsShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/program/ProgramStageSectionModelsShould.java index 9ec48ef4c4..393ea65428 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/program/ProgramStageSectionModelsShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/program/ProgramStageSectionModelsShould.java @@ -54,6 +54,9 @@ public class ProgramStageSectionModelsShould { private final Date date; private final String dateString; + private final ProgramStageSectionRenderingType DESKTOP_RENDER_TYPE = ProgramStageSectionRenderingType.MATRIX; + private final ProgramStageSectionRenderingType MOBILE_RENDER_TYPE = ProgramStageSectionRenderingType.LISTING; + public ProgramStageSectionModelsShould() { this.date = new Date(); this.dateString = BaseIdentifiableObject.DATE_FORMAT.format(date); @@ -64,11 +67,11 @@ public void create_model_when_created_from_database_cursor() { MatrixCursor cursor = new MatrixCursor(new String[]{ Columns.ID, Columns.UID, Columns.CODE, Columns.NAME, Columns.DISPLAY_NAME, Columns.CREATED, Columns.LAST_UPDATED, - Columns.SORT_ORDER, Columns.PROGRAM_STAGE + Columns.SORT_ORDER, Columns.PROGRAM_STAGE, Columns.DESKTOP_RENDER_TYPE, Columns.MOBILE_RENDER_TYPE }); cursor.addRow(new Object[]{ ID, UID, CODE, NAME, DISPLAY_NAME, dateString, dateString, - SORT_ORDER, PROGRAM_STAGE + SORT_ORDER, PROGRAM_STAGE, DESKTOP_RENDER_TYPE, MOBILE_RENDER_TYPE }); cursor.moveToFirst(); @@ -84,6 +87,8 @@ public void create_model_when_created_from_database_cursor() { assertThat(model.lastUpdated()).isEqualTo(date); assertThat(model.sortOrder()).isEqualTo(SORT_ORDER); assertThat(model.programStage()).isEqualTo(PROGRAM_STAGE); + assertThat(model.desktopRenderType()).isEqualTo(DESKTOP_RENDER_TYPE); + assertThat(model.mobileRenderType()).isEqualTo(MOBILE_RENDER_TYPE); } @Test @@ -98,6 +103,8 @@ public void create_content_values_when_created_from_builder() { .lastUpdated(date) .sortOrder(SORT_ORDER) .programStage(PROGRAM_STAGE) + .desktopRenderType(DESKTOP_RENDER_TYPE) + .mobileRenderType(MOBILE_RENDER_TYPE) .build(); ContentValues contentValues = model.toContentValues(); @@ -110,5 +117,7 @@ public void create_content_values_when_created_from_builder() { assertThat(contentValues.getAsString(Columns.LAST_UPDATED)).isEqualTo(dateString); assertThat(contentValues.getAsInteger(Columns.SORT_ORDER)).isEqualTo(SORT_ORDER); assertThat(contentValues.getAsString(Columns.PROGRAM_STAGE)).isEqualTo(PROGRAM_STAGE); + assertThat(contentValues.getAsString(Columns.DESKTOP_RENDER_TYPE)).isEqualTo(DESKTOP_RENDER_TYPE.toString()); + assertThat(contentValues.getAsString(Columns.MOBILE_RENDER_TYPE)).isEqualTo(MOBILE_RENDER_TYPE.toString()); } } diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/program/ProgramStageSectionStoreShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/program/ProgramStageSectionStoreShould.java index e914f26ea6..5c34e9ce8d 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/program/ProgramStageSectionStoreShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/program/ProgramStageSectionStoreShould.java @@ -82,6 +82,10 @@ public class ProgramStageSectionStoreShould extends AbsStoreTestCase { private ProgramStageSectionStore store; + private final ProgramStageSectionRenderingType DESKTOP_RENDER_TYPE = ProgramStageSectionRenderingType.MATRIX; + private final ProgramStageSectionRenderingType MOBILE_RENDER_TYPE = ProgramStageSectionRenderingType.LISTING; + + public ProgramStageSectionStoreShould() { this.date = new Date(); this.dateString = BaseIdentifiableObject.DATE_FORMAT.format(date); @@ -118,7 +122,9 @@ public void insert_program_stage_section_in_data_base_when_insert() { date, date, SORT_ORDER, - PROGRAM_STAGE + PROGRAM_STAGE, + DESKTOP_RENDER_TYPE, + MOBILE_RENDER_TYPE ); Cursor cursor = database().query(ProgramStageSectionModel.TABLE, @@ -145,8 +151,7 @@ public void insert_deferrable_program_stage_section_in_data_base_when_insert() { database().beginTransaction(); long rowId = store.insert(UID, CODE, NAME, DISPLAY_NAME, date, date, SORT_ORDER, - deferredProgramStage - ); + deferredProgramStage, DESKTOP_RENDER_TYPE, MOBILE_RENDER_TYPE); ContentValues programStage = CreateProgramStageUtils.create(3L, deferredProgramStage, PROGRAM); database().insert(ProgramStageModel.TABLE, null, programStage); database().setTransactionSuccessful(); @@ -195,7 +200,9 @@ public void throw_sqlite_constraint_exception_when_insert_program_stage_section_ date, date, SORT_ORDER, - WRONG_UID // supplying wrong uid + WRONG_UID, // supplying wrong uid + DESKTOP_RENDER_TYPE, + MOBILE_RENDER_TYPE ); } @@ -220,7 +227,7 @@ public void update_in_data_base_when_update() throws Exception { // update program stage section with new display name int update = store.update( UID, CODE, NAME, updatedDisplayName, - date, date, SORT_ORDER, PROGRAM_STAGE, UID + date, date, SORT_ORDER, PROGRAM_STAGE, DESKTOP_RENDER_TYPE, MOBILE_RENDER_TYPE, UID ); // check that store returns 1 after successful update @@ -262,26 +269,31 @@ public void delete_in_data_base_when_delete() throws Exception { @Test(expected = IllegalArgumentException.class) public void throw_illegal_argument_exception_when_insert_null_uid() { - store.insert(null, CODE, NAME, DISPLAY_NAME, date, date, SORT_ORDER, PROGRAM_STAGE); + store.insert(null, CODE, NAME, DISPLAY_NAME, date, date, SORT_ORDER, PROGRAM_STAGE, DESKTOP_RENDER_TYPE, + MOBILE_RENDER_TYPE); } @Test(expected = IllegalArgumentException.class) public void throw_illegal_argument_exception_when_insert_null_program_stage() { - store.insert(UID, CODE, NAME, DISPLAY_NAME, date, date, SORT_ORDER, null); + store.insert(UID, CODE, NAME, DISPLAY_NAME, date, date, SORT_ORDER, null, DESKTOP_RENDER_TYPE, + MOBILE_RENDER_TYPE); } @Test(expected = IllegalArgumentException.class) public void throw_illegal_argument_exception_when_update_null_uid() { - store.update(null, CODE, NAME, DISPLAY_NAME, date, date, SORT_ORDER, PROGRAM_STAGE, UID); + store.update(null, CODE, NAME, DISPLAY_NAME, date, date, SORT_ORDER, PROGRAM_STAGE, DESKTOP_RENDER_TYPE, + MOBILE_RENDER_TYPE, UID); } @Test(expected = IllegalArgumentException.class) public void throw_illegal_argument_exception_when_update_null_program_stage() { - store.update(UID, CODE, NAME, DISPLAY_NAME, date, date, SORT_ORDER, null, UID); + store.update(UID, CODE, NAME, DISPLAY_NAME, date, date, SORT_ORDER, null, DESKTOP_RENDER_TYPE, + MOBILE_RENDER_TYPE, UID); } @Test(expected = IllegalArgumentException.class) public void throw_illegal_argument_exception_when_update_null_where_uid() { - store.update(UID, CODE, NAME, DISPLAY_NAME, date, date, SORT_ORDER, PROGRAM_STAGE, null); + store.update(UID, CODE, NAME, DISPLAY_NAME, date, date, SORT_ORDER, PROGRAM_STAGE, DESKTOP_RENDER_TYPE, + MOBILE_RENDER_TYPE, null); } @Test(expected = IllegalArgumentException.class) diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/program/ProgramStoreShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/program/ProgramStoreShould.java index 8d9e1fb245..c57a3923ae 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/program/ProgramStoreShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/program/ProgramStoreShould.java @@ -86,7 +86,8 @@ public class ProgramStoreShould extends AbsStoreTestCase { Columns.RELATIONSHIP_TEXT, Columns.RELATED_PROGRAM, Columns.TRACKED_ENTITY, - Columns.CATEGORY_COMBO + Columns.CATEGORY_COMBO, + Columns.ACCESS_DATA_WRITE }; //BaseIdentifiableModel attributes: @@ -129,6 +130,8 @@ public class ProgramStoreShould extends AbsStoreTestCase { private static final Long CATEGORY_COMBO_ID = 4L; private static final String CATEGORY_COMBO = "CategoryComboUid"; + + private static final Boolean ACCESS_DATA_WRITE = true; private final Date date; private final String dateString; @@ -190,7 +193,8 @@ public void insert_program_in_data_base_when_insert() { RELATIONSHIP_TEXT, null, TRACKED_ENTITY, - CATEGORY_COMBO + CATEGORY_COMBO, + ACCESS_DATA_WRITE ); Cursor cursor = database().query(ProgramModel.TABLE, PROGRAM_PROJECTION, null, null, null, null, null, null); @@ -226,8 +230,9 @@ public void insert_program_in_data_base_when_insert() { RELATIONSHIP_TEXT, null, TRACKED_ENTITY, - CATEGORY_COMBO - ).isExhausted(); + CATEGORY_COMBO, + toInteger(ACCESS_DATA_WRITE) + ).isExhausted(); } @Test @@ -252,7 +257,7 @@ public void insert_program_with_deferred_foreign_key_in_data_base_when_insert() VERSION, ONLY_ENROLL_ONCE, ENROLLMENT_DATE_LABEL, DISPLAY_INCIDENT_DATE, INCIDENT_DATE_LABEL, REGISTRATION, SELECT_ENROLLMENT_DATES_IN_FUTURE, DATA_ENTRY_METHOD, IGNORE_OVERDUE_EVENTS, RELATIONSHIP_FROM_A, SELECT_INCIDENT_DATES_IN_FUTURE, CAPTURE_COORDINATES, USE_FIRST_STAGE_DURING_REGISTRATION, DISPLAY_FRONT_PAGE_LIST, PROGRAM_TYPE, - deferredRelationshipTypeUid, RELATIONSHIP_TEXT, UID2, deferredTrackedEntityUid, deferredCategoryComboUid + deferredRelationshipTypeUid, RELATIONSHIP_TEXT, UID2, deferredTrackedEntityUid, deferredCategoryComboUid, ACCESS_DATA_WRITE ); long rowId2 = store.insert( @@ -261,7 +266,7 @@ public void insert_program_with_deferred_foreign_key_in_data_base_when_insert() VERSION, ONLY_ENROLL_ONCE, ENROLLMENT_DATE_LABEL, DISPLAY_INCIDENT_DATE, INCIDENT_DATE_LABEL, REGISTRATION, SELECT_ENROLLMENT_DATES_IN_FUTURE, DATA_ENTRY_METHOD, IGNORE_OVERDUE_EVENTS, RELATIONSHIP_FROM_A, SELECT_INCIDENT_DATES_IN_FUTURE, CAPTURE_COORDINATES, USE_FIRST_STAGE_DURING_REGISTRATION, DISPLAY_FRONT_PAGE_LIST, PROGRAM_TYPE, - RELATIONSHIP_TYPE, RELATIONSHIP_TEXT, UID, TRACKED_ENTITY, CATEGORY_COMBO + RELATIONSHIP_TYPE, RELATIONSHIP_TEXT, UID, TRACKED_ENTITY, CATEGORY_COMBO, ACCESS_DATA_WRITE ); database().setTransactionSuccessful(); database().endTransaction(); @@ -276,7 +281,7 @@ public void insert_program_with_deferred_foreign_key_in_data_base_when_insert() VERSION, toInteger(ONLY_ENROLL_ONCE), ENROLLMENT_DATE_LABEL, toInteger(DISPLAY_INCIDENT_DATE), INCIDENT_DATE_LABEL, toInteger(REGISTRATION), toInteger(SELECT_ENROLLMENT_DATES_IN_FUTURE), toInteger(DATA_ENTRY_METHOD), toInteger(IGNORE_OVERDUE_EVENTS), toInteger(RELATIONSHIP_FROM_A), toInteger(SELECT_INCIDENT_DATES_IN_FUTURE), toInteger(CAPTURE_COORDINATES), toInteger(USE_FIRST_STAGE_DURING_REGISTRATION), toInteger(DISPLAY_FRONT_PAGE_LIST), PROGRAM_TYPE, deferredRelationshipTypeUid, RELATIONSHIP_TEXT, - UID2, deferredTrackedEntityUid, deferredCategoryComboUid + UID2, deferredTrackedEntityUid, deferredCategoryComboUid, toInteger(ACCESS_DATA_WRITE) ); assertThatCursor(cursor).hasRow( UID2, CODE, NAME, DISPLAY_NAME, dateString, @@ -284,7 +289,7 @@ VERSION, toInteger(ONLY_ENROLL_ONCE), ENROLLMENT_DATE_LABEL, toInteger(DISPLAY_I DISPLAY_DESCRIPTION, VERSION, toInteger(ONLY_ENROLL_ONCE), ENROLLMENT_DATE_LABEL, toInteger(DISPLAY_INCIDENT_DATE), INCIDENT_DATE_LABEL, toInteger(REGISTRATION), toInteger(SELECT_ENROLLMENT_DATES_IN_FUTURE), toInteger(DATA_ENTRY_METHOD), toInteger(IGNORE_OVERDUE_EVENTS), toInteger(RELATIONSHIP_FROM_A), toInteger(SELECT_INCIDENT_DATES_IN_FUTURE), toInteger(CAPTURE_COORDINATES), toInteger(USE_FIRST_STAGE_DURING_REGISTRATION), toInteger(DISPLAY_FRONT_PAGE_LIST), PROGRAM_TYPE, - RELATIONSHIP_TYPE, RELATIONSHIP_TEXT, UID, TRACKED_ENTITY, CATEGORY_COMBO + RELATIONSHIP_TYPE, RELATIONSHIP_TEXT, UID, TRACKED_ENTITY, CATEGORY_COMBO, toInteger(ACCESS_DATA_WRITE) ); assertThatCursor(cursor).isExhausted(); } @@ -293,14 +298,14 @@ INCIDENT_DATE_LABEL, toInteger(REGISTRATION), toInteger(SELECT_ENROLLMENT_DATES_ public void throw_sqlite_constraint_exception_when__persistProgramWithInvalidRelationshipTypeForeignKey() { store.insert(UID, null, NAME, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, RELATIONSHIP_FROM_A, null, null, null, null, PROGRAM_TYPE, - "wrong", null, null, TRACKED_ENTITY, CATEGORY_COMBO); + "wrong", null, null, TRACKED_ENTITY, CATEGORY_COMBO, ACCESS_DATA_WRITE); } @Test(expected = SQLiteConstraintException.class) public void throw_sqlite_constraint_exception_when__persistProgramWithInvalidTrackedEntityForeignKey() { store.insert(UID, null, NAME, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, RELATIONSHIP_FROM_A, null, null, null, null, PROGRAM_TYPE, - RELATIONSHIP_TYPE, null, null, "wrong", CATEGORY_COMBO); + RELATIONSHIP_TYPE, null, null, "wrong", CATEGORY_COMBO, ACCESS_DATA_WRITE); } @Test @@ -308,14 +313,14 @@ public void insert_program_in_data_base_when_insert_nullable_program() { long rowId = store.insert( UID, null, NAME, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, RELATIONSHIP_FROM_A, null, - null, null, null, PROGRAM_TYPE, null, null, null, null, null); + null, null, null, PROGRAM_TYPE, null, null, null, null, null, false); Cursor cursor = database().query(ProgramModel.TABLE, PROGRAM_PROJECTION, null, null, null, null, null, null); assertThat(rowId).isEqualTo(1L); assertThatCursor(cursor).hasRow(UID, null, NAME, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, toInteger(RELATIONSHIP_FROM_A), null, - null, null, null, PROGRAM_TYPE, null, null, null, null, null).isExhausted(); + null, null, null, PROGRAM_TYPE, null, null, null, null, null, toInteger(false)).isExhausted(); } @Test @@ -350,7 +355,8 @@ public void delete_program_when_delete_relationship_type_foreign_key() { RELATIONSHIP_TEXT, null, TRACKED_ENTITY, - CATEGORY_COMBO + CATEGORY_COMBO, + ACCESS_DATA_WRITE ); database().delete(RelationshipTypeModel.TABLE, @@ -392,7 +398,8 @@ public void delete_program_when_delete_tracked_entity_foreign_key() { RELATIONSHIP_TEXT, null, TRACKED_ENTITY, - CATEGORY_COMBO + CATEGORY_COMBO, + ACCESS_DATA_WRITE ); database().delete(TrackedEntityModel.TABLE, @@ -429,7 +436,8 @@ public void update_program_in_data_base_when_update() throws Exception { SELECT_ENROLLMENT_DATES_IN_FUTURE, DATA_ENTRY_METHOD, IGNORE_OVERDUE_EVENTS, RELATIONSHIP_FROM_A, SELECT_INCIDENT_DATES_IN_FUTURE, CAPTURE_COORDINATES, USE_FIRST_STAGE_DURING_REGISTRATION, DISPLAY_FRONT_PAGE_LIST, PROGRAM_TYPE, - null, null, null, null, null, UID + null, null, null, null, null, + ACCESS_DATA_WRITE, UID ); // check that store returns 1 when successfully update @@ -475,7 +483,7 @@ public void throw_illegal_argument_exception_when_insert_null_uid() { INCIDENT_DATE_LABEL, REGISTRATION, SELECT_ENROLLMENT_DATES_IN_FUTURE, DATA_ENTRY_METHOD, IGNORE_OVERDUE_EVENTS, RELATIONSHIP_FROM_A, SELECT_INCIDENT_DATES_IN_FUTURE, CAPTURE_COORDINATES, USE_FIRST_STAGE_DURING_REGISTRATION, DISPLAY_FRONT_PAGE_LIST, PROGRAM_TYPE, RELATIONSHIP_TYPE, - RELATIONSHIP_TEXT, null, TRACKED_ENTITY, CATEGORY_COMBO); + RELATIONSHIP_TEXT, null, TRACKED_ENTITY, CATEGORY_COMBO, ACCESS_DATA_WRITE); } @Test(expected = IllegalArgumentException.class) @@ -485,7 +493,7 @@ public void throw_illegal_argument_exception_when_update_null_uid() { INCIDENT_DATE_LABEL, REGISTRATION, SELECT_ENROLLMENT_DATES_IN_FUTURE, DATA_ENTRY_METHOD, IGNORE_OVERDUE_EVENTS, RELATIONSHIP_FROM_A, SELECT_INCIDENT_DATES_IN_FUTURE, CAPTURE_COORDINATES, USE_FIRST_STAGE_DURING_REGISTRATION, DISPLAY_FRONT_PAGE_LIST, PROGRAM_TYPE, RELATIONSHIP_TYPE, - RELATIONSHIP_TEXT, null, TRACKED_ENTITY, CATEGORY_COMBO, UID); + RELATIONSHIP_TEXT, null, TRACKED_ENTITY, CATEGORY_COMBO, ACCESS_DATA_WRITE, UID); } @Test(expected = IllegalArgumentException.class) @@ -495,7 +503,7 @@ public void throw_illegal_argument_exception_when_update_null_where_uid() { INCIDENT_DATE_LABEL, REGISTRATION, SELECT_ENROLLMENT_DATES_IN_FUTURE, DATA_ENTRY_METHOD, IGNORE_OVERDUE_EVENTS, RELATIONSHIP_FROM_A, SELECT_INCIDENT_DATES_IN_FUTURE, CAPTURE_COORDINATES, USE_FIRST_STAGE_DURING_REGISTRATION, DISPLAY_FRONT_PAGE_LIST, PROGRAM_TYPE, RELATIONSHIP_TYPE, - RELATIONSHIP_TEXT, null, TRACKED_ENTITY, CATEGORY_COMBO,null); + RELATIONSHIP_TEXT, null, TRACKED_ENTITY, CATEGORY_COMBO,ACCESS_DATA_WRITE,null); } @Test(expected = IllegalArgumentException.class) diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/trackedentity/TrackedEntityInstanceCallMockIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/trackedentity/TrackedEntityInstanceCallMockIntegrationShould.java index a099d3291f..219fd8e9d9 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/trackedentity/TrackedEntityInstanceCallMockIntegrationShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/trackedentity/TrackedEntityInstanceCallMockIntegrationShould.java @@ -98,16 +98,7 @@ public void remove_data_removed_in_server_after_second_download() } private void givenAMetadataInDatabase() throws Exception { - dhis2MockServer.enqueueMockResponse("system_info.json"); - dhis2MockServer.enqueueMockResponse("user.json"); - dhis2MockServer.enqueueMockResponse("organisationUnits.json"); - dhis2MockServer.enqueueMockResponse("categories.json"); - dhis2MockServer.enqueueMockResponse("category_combos.json"); - dhis2MockServer.enqueueMockResponse("programs.json"); - dhis2MockServer.enqueueMockResponse("tracked_entities.json"); - dhis2MockServer.enqueueMockResponse("option_sets.json"); - dhis2MockServer.enqueueMockResponse("data_sets.json"); - dhis2MockServer.enqueueMockResponse("data_elements.json"); + dhis2MockServer.enqueueMetadataResponses(); d2.syncMetaData().call(); } diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/user/UserAuthenticateCallMockIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/user/UserAuthenticateCallMockIntegrationShould.java index 942e3f1cea..cc6413cf07 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/user/UserAuthenticateCallMockIntegrationShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/user/UserAuthenticateCallMockIntegrationShould.java @@ -232,8 +232,6 @@ public void setUp() throws IOException { databaseAdapter()); AuthenticatedUserStore authenticatedUserStore = new AuthenticatedUserStoreImpl( databaseAdapter()); - UserOrganisationUnitLinkStore userOrganisationUnitLinkStore = - new UserOrganisationUnitLinkStoreImpl(databaseAdapter()); ResourceStore resourceStore = new ResourceStoreImpl(databaseAdapter()); ResourceHandler resourceHandler = new ResourceHandler(resourceStore); UserCredentialsHandler userCredentialsHandler = new UserCredentialsHandler( @@ -241,7 +239,7 @@ public void setUp() throws IOException { OrganisationUnitHandler organisationUnitHandler = new OrganisationUnitHandler( organisationUnitStore, new UserOrganisationUnitLinkStoreImpl(databaseAdapter()), - new OrganisationUnitProgramLinkStoreImpl(databaseAdapter())); + new OrganisationUnitProgramLinkStoreImpl(databaseAdapter()), null); authenticateUserCall = new UserAuthenticateCall(userService, databaseAdapter(), userStore, userCredentialsHandler, resourceHandler, diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/user/UserCallMockIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/user/UserCallMockIntegrationShould.java index d218ea82aa..26343316fb 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/user/UserCallMockIntegrationShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/user/UserCallMockIntegrationShould.java @@ -37,11 +37,6 @@ import org.hisp.dhis.android.core.common.BaseIdentifiableObject; import org.hisp.dhis.android.core.data.api.FieldsConverterFactory; import org.hisp.dhis.android.core.data.database.AbsStoreTestCase; -import org.hisp.dhis.android.core.organisationunit.OrganisationUnitHandler; -import org.hisp.dhis.android.core.organisationunit.OrganisationUnitProgramLinkStore; -import org.hisp.dhis.android.core.organisationunit.OrganisationUnitProgramLinkStoreImpl; -import org.hisp.dhis.android.core.organisationunit.OrganisationUnitStore; -import org.hisp.dhis.android.core.organisationunit.OrganisationUnitStoreImpl; import org.hisp.dhis.android.core.program.CreateProgramUtils; import org.hisp.dhis.android.core.program.ProgramModel; import org.hisp.dhis.android.core.resource.ResourceStore; @@ -90,7 +85,6 @@ public class UserCallMockIntegrationShould extends AbsStoreTestCase { private MockWebServer mockWebServer; private UserCall userCall; - private OrganisationUnitHandler organisationUnitHandler; @Override @Before @@ -218,24 +212,14 @@ public void setUp() throws IOException { UserService userService = retrofit.create(UserService.class); - OrganisationUnitStore organisationUnitStore = new OrganisationUnitStoreImpl(databaseAdapter()); - UserOrganisationUnitLinkStore userOrganisationUnitStore = - new UserOrganisationUnitLinkStoreImpl(databaseAdapter()); UserCredentialsStore userCredentialsStore = new UserCredentialsStoreImpl(databaseAdapter()); UserRoleStore userRoleStore = new UserRoleStoreImpl(databaseAdapter()); UserStore userStore = new UserStoreImpl(databaseAdapter()); - UserRoleProgramLinkStore userRoleProgramLinkStore = new UserRoleProgramLinkStoreImpl(databaseAdapter()); - OrganisationUnitProgramLinkStore organisationUnitProgramLinkStore = - new OrganisationUnitProgramLinkStoreImpl(databaseAdapter()); ResourceStore resourceStore = new ResourceStoreImpl(databaseAdapter()); - organisationUnitHandler = new OrganisationUnitHandler( - organisationUnitStore, userOrganisationUnitStore, organisationUnitProgramLinkStore - ); userCall = new UserCall(userService, databaseAdapter(), - userStore, userCredentialsStore, userRoleStore, resourceStore, new Date(), - userRoleProgramLinkStore); + userStore, userCredentialsStore, userRoleStore, resourceStore, new Date()); ContentValues program1 = CreateProgramUtils.create(1L, "eBAyeGv0exc", null, null, null); ContentValues program2 = CreateProgramUtils.create(2L, "ur1Edk5Oe2n", null, null, null); @@ -326,11 +310,6 @@ public void persist_user_roles_in_data_base_when_call() throws Exception { UserRoleModel.Columns.LAST_UPDATED }; - String[] userRoleProgramLinkModelProjection = { - UserRoleProgramLinkModel.Columns.USER_ROLE, - UserRoleProgramLinkModel.Columns.PROGRAM - }; - Cursor userRoleCursor = database().query(UserRoleModel.TABLE, userRoleProjection, UserRoleModel.Columns.UID + "=?", new String[]{"cUlTcejWree"}, null, null, null); @@ -342,17 +321,6 @@ public void persist_user_roles_in_data_base_when_call() throws Exception { null, null ).isExhausted(); - - Cursor linkModelCursor = database().query(UserRoleProgramLinkModel.TABLE, userRoleProgramLinkModelProjection, - UserRoleProgramLinkModel.Columns.USER_ROLE + "=?" + - " AND " + - UserRoleProgramLinkModel.Columns.PROGRAM + "=?", new String[]{"cUlTcejWree", "ur1Edk5Oe2n"}, - null, null, null); - - assertThatCursor(linkModelCursor).hasRow( - "cUlTcejWree", - "ur1Edk5Oe2n" - ).isExhausted(); } @After diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/user/UserRoleProgramLinkStoreShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/user/UserRoleProgramLinkStoreShould.java deleted file mode 100644 index 4ee7ef3711..0000000000 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/user/UserRoleProgramLinkStoreShould.java +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright (c) 2017, University of Oslo - * - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * Neither the name of the HISP project nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package org.hisp.dhis.android.core.user; - -import android.content.ContentValues; -import android.database.Cursor; -import android.database.sqlite.SQLiteConstraintException; - -import org.hisp.dhis.android.core.data.database.AbsStoreTestCase; -import org.hisp.dhis.android.core.program.CreateProgramUtils; -import org.hisp.dhis.android.core.program.ProgramModel; -import org.hisp.dhis.android.core.relationship.CreateRelationshipTypeUtils; -import org.hisp.dhis.android.core.relationship.RelationshipTypeModel; -import org.hisp.dhis.android.core.trackedentity.CreateTrackedEntityUtils; -import org.hisp.dhis.android.core.trackedentity.TrackedEntityModel; -import org.hisp.dhis.android.core.user.UserRoleProgramLinkModel.Columns; -import org.junit.Before; -import org.junit.Test; - -import java.io.IOException; - -import static com.google.common.truth.Truth.assertThat; -import static org.hisp.dhis.android.core.data.database.CursorAssert.assertThatCursor; - -public class UserRoleProgramLinkStoreShould extends AbsStoreTestCase { - private static final String[] PROJECTION = {Columns.USER_ROLE, Columns.PROGRAM}; - - public static final long ID = 1L; - private static final String USER_ROLE_UID = "test_user_role_uid"; - private static final String PROGRAM_UID = "test_program_uid"; - //foreign keys to program: - private static final long TRACKED_ENTITY_ID = 1L; - private static final String TRACKED_ENTITY_UID = "trackedEntityUid"; - private static final long RELATIONSHIP_TYPE_ID = 3L; - - private static final String RELATIONSHIP_TYPE_UID = "relationshipTypeUid"; - - private UserRoleProgramLinkStore store; - - @Before - @Override - public void setUp() throws IOException { - super.setUp(); - store = new UserRoleProgramLinkStoreImpl(databaseAdapter()); - ContentValues userRole = CreateUserRoleUtils.create(ID, USER_ROLE_UID); - ContentValues trackedEntity = CreateTrackedEntityUtils.create(TRACKED_ENTITY_ID, TRACKED_ENTITY_UID); - ContentValues relationshipType = CreateRelationshipTypeUtils.create(RELATIONSHIP_TYPE_ID, - RELATIONSHIP_TYPE_UID); - ContentValues program = CreateProgramUtils.create(1L, PROGRAM_UID, - RELATIONSHIP_TYPE_UID, null, TRACKED_ENTITY_UID); - database().insert(UserRoleModel.TABLE, null, userRole); - database().insert(TrackedEntityModel.TABLE, null, trackedEntity); - database().insert(RelationshipTypeModel.TABLE, null, relationshipType); - database().insert(ProgramModel.TABLE, null, program); - } - - @Test - public void insert_in_data_base_when_insert() { - long rowId = store.insert(USER_ROLE_UID, PROGRAM_UID); - Cursor cursor = database().query(UserRoleProgramLinkModel.TABLE, PROJECTION, null, null, null, null, null); - assertThat(rowId).isEqualTo(1L); - assertThatCursor(cursor).hasRow(USER_ROLE_UID, PROGRAM_UID).isExhausted(); - } - - @Test - public void insert_in_data_base_when_insert_deferrable_row() { - final String deferredUserRole = "deferredUserRole"; - final String deferredProgram = "deferredProgram"; - - database().beginTransaction(); - long rowId = store.insert(deferredUserRole, deferredProgram); - ContentValues userRole = CreateUserRoleUtils.create(3L, deferredUserRole); - ContentValues program = CreateProgramUtils.create(3L, deferredProgram, - RELATIONSHIP_TYPE_UID, null, TRACKED_ENTITY_UID); - database().insert(UserRoleModel.TABLE, null, userRole); - database().insert(ProgramModel.TABLE, null, program); - database().setTransactionSuccessful(); - database().endTransaction(); - - Cursor cursor = database().query(UserRoleProgramLinkModel.TABLE, PROJECTION, null, null, null, null, null); - assertThat(rowId).isEqualTo(1L); - assertThatCursor(cursor).hasRow(deferredUserRole, deferredProgram).isExhausted(); - } - - @Test - public void update_and_not_insert_when_update() { - long rowId = store.update(USER_ROLE_UID, PROGRAM_UID, USER_ROLE_UID, PROGRAM_UID); - Cursor cursor = database().query(UserRoleProgramLinkModel.TABLE, PROJECTION, null, null, null, null, null); - assertThat(rowId).isEqualTo(0); - assertThatCursor(cursor).isExhausted(); - } - - @Test - public void update_when_update_existing_user_role_program_link() { - final String oldUserRoleUid = "oldUserRoleUid"; - final String oldProgramUid = "oldProgramUid"; - //insert old foreign key tables: - ContentValues userRole = CreateUserRoleUtils.create(3L, oldUserRoleUid); - ContentValues program = CreateProgramUtils.create(3L, oldProgramUid, - RELATIONSHIP_TYPE_UID, null, TRACKED_ENTITY_UID); - database().insert(UserRoleModel.TABLE, null, userRole); - database().insert(ProgramModel.TABLE, null, program); - - ContentValues contentValues = new ContentValues(); - contentValues.put(Columns.USER_ROLE, oldUserRoleUid); - contentValues.put(Columns.PROGRAM, oldProgramUid); - database().insert(UserRoleProgramLinkModel.TABLE, null, contentValues); - - long returnValue = store.update(USER_ROLE_UID, PROGRAM_UID, oldUserRoleUid, oldProgramUid); - - Cursor cursor = database().query(UserRoleProgramLinkModel.TABLE, PROJECTION, null, null, null, null, null); - - assertThat(returnValue).isEqualTo(1L); - assertThatCursor(cursor).hasRow(USER_ROLE_UID, PROGRAM_UID).isExhausted(); - } - - @Test - public void delete_in_data_base_when_delete_row() { - ContentValues contentValues = new ContentValues(); - contentValues.put(Columns.USER_ROLE, USER_ROLE_UID); - contentValues.put(Columns.PROGRAM, PROGRAM_UID); - - database().insert(UserRoleProgramLinkModel.TABLE, null, contentValues); - int returnValue = store.delete(USER_ROLE_UID, PROGRAM_UID); - - Cursor cursor = database().query(UserRoleProgramLinkModel.TABLE, PROJECTION, null, null, null, null, null); - - assertThat(returnValue).isEqualTo(1); - assertThatCursor(cursor).isExhausted(); - } - - @Test - public void delete_user_role_program_link_in_data_base_when_delete_user_role_foreign_key() { - store.insert(USER_ROLE_UID, PROGRAM_UID); - database().delete(UserRoleModel.TABLE, UserRoleModel.Columns.UID + "=?", new String[]{USER_ROLE_UID}); - Cursor cursor = database().query(UserRoleProgramLinkModel.TABLE, PROJECTION, null, null, null, null, null); - assertThatCursor(cursor).isExhausted(); - } - - @Test - public void delete_user_role_program_link_in_data_base_when_delete_program_foreign_key() { - store.insert(USER_ROLE_UID, PROGRAM_UID); - database().delete(ProgramModel.TABLE, ProgramModel.Columns.UID + "=?", new String[]{PROGRAM_UID}); - Cursor cursor = database().query(UserRoleProgramLinkModel.TABLE, PROJECTION, null, null, null, null, null); - assertThatCursor(cursor).isExhausted(); - } - - @Test(expected = SQLiteConstraintException.class) - public void throw_sqlite_constraint_exception_when_insert_user_role_program_link_with_invalid_user_foreign_key() { - store.insert("wrong", PROGRAM_UID); - } - - @Test(expected = SQLiteConstraintException.class) - public void throw_sqlite_constraint_exception_when_insert_user_role_program_link_with_organisation_unit_foreign_key() { - store.insert(USER_ROLE_UID, "wrong"); - } - - @Test(expected = IllegalArgumentException.class) - - public void throw_illegal_argument_exception_when_insert_null_uid_arg() { - store.insert(null, PROGRAM_UID); - } - - @Test(expected = IllegalArgumentException.class) - public void throw_illegal_argument_exception_when_insert_null_program_arg() { - store.insert(USER_ROLE_UID, null); - } - - @Test(expected = IllegalArgumentException.class) - public void throw_illegal_argument_exception_when_update_null_user_role_arg() { - store.update(null, PROGRAM_UID, USER_ROLE_UID, PROGRAM_UID); - } - - @Test(expected = IllegalArgumentException.class) - public void throw_illegal_argument_exception_when_update_null_program_arg() { - store.update(USER_ROLE_UID, null, USER_ROLE_UID, PROGRAM_UID); - } - - @Test(expected = IllegalArgumentException.class) - public void throw_illegal_argument_exception_when_update_null_where_user_role_arg() { - store.update(USER_ROLE_UID, PROGRAM_UID, null, PROGRAM_UID); - } - - @Test(expected = IllegalArgumentException.class) - public void throw_illegal_argument_exception_when_update_null_where_program_arg() { - store.update( USER_ROLE_UID, PROGRAM_UID, USER_ROLE_UID, null); - } - - @Test(expected = IllegalArgumentException.class) - public void throw_illegal_argument_exception_when_delete_user_role_arg() { - store.delete(null, PROGRAM_UID); - } - - @Test(expected = IllegalArgumentException.class) - public void throw_illegal_argument_exception_when_delete_program_arg() { - store.delete(USER_ROLE_UID, null); - } -} diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/utils/ColumnsAsserts.java b/core/src/androidTest/java/org/hisp/dhis/android/core/utils/ColumnsAsserts.java index 05ba3f9be9..33c4baa901 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/utils/ColumnsAsserts.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/utils/ColumnsAsserts.java @@ -41,7 +41,7 @@ */ public class ColumnsAsserts { - public static void testIdentifiableModelColumns(List columnsList) { + private static void testIdentifiableModelColumns(List columnsList) { assertThat(columnsList.contains(BaseIdentifiableObjectModel.Columns.UID)).isEqualTo(true); assertThat(columnsList.contains(BaseIdentifiableObjectModel.Columns.CODE)).isEqualTo(true); assertThat(columnsList.contains(BaseIdentifiableObjectModel.Columns.NAME)).isEqualTo(true); @@ -54,7 +54,7 @@ public static void testIdentifiableModelColumns(String[] columns) { testIdentifiableModelColumns(Arrays.asList(columns)); } - public static void testNameableModelColumns(List columnsList) { + private static void testNameableModelColumns(List columnsList) { assertThat(columnsList.contains(BaseNameableObjectModel.Columns.SHORT_NAME)).isEqualTo(true); assertThat(columnsList.contains(BaseNameableObjectModel.Columns.DISPLAY_SHORT_NAME)).isEqualTo(true); assertThat(columnsList.contains(BaseNameableObjectModel.Columns.DESCRIPTION)).isEqualTo(true); diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/utils/ContentValuesTestUtils.java b/core/src/androidTest/java/org/hisp/dhis/android/core/utils/ContentValuesTestUtils.java deleted file mode 100644 index 8e9ba8c1ba..0000000000 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/utils/ContentValuesTestUtils.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2017, University of Oslo - * - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * Neither the name of the HISP project nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.hisp.dhis.android.core.utils; - -import android.content.ContentValues; - -import org.hisp.dhis.android.core.common.BaseIdentifiableObjectModel; -import org.hisp.dhis.android.core.common.BaseModel; -import org.hisp.dhis.android.core.common.BaseNameableObjectModel; - -import static com.google.common.truth.Truth.assertThat; - -/** - * A collection of convenience functions/abstractions to be used by the tests. - */ -public class ContentValuesTestUtils { - - private static void testModelContentValues(ContentValues contentValues, BaseModel m) { - assertThat(contentValues.getAsLong(BaseModel.Columns.ID)).isEqualTo(m.id()); - } - - public static void testIdentifiableModelContentValues(ContentValues contentValues, BaseIdentifiableObjectModel m) { - testModelContentValues(contentValues, m); - assertThat(contentValues.getAsString(BaseIdentifiableObjectModel.Columns.UID)).isEqualTo(m.uid()); - assertThat(contentValues.getAsString(BaseIdentifiableObjectModel.Columns.CODE)).isEqualTo(m.code()); - assertThat(contentValues.getAsString(BaseIdentifiableObjectModel.Columns.NAME)).isEqualTo(m.name()); - assertThat(contentValues.getAsString(BaseIdentifiableObjectModel.Columns.DISPLAY_NAME)).isEqualTo(m.displayName()); - assertThat(contentValues.getAsString(BaseIdentifiableObjectModel.Columns.CREATED)).isEqualTo(m.createdStr()); - assertThat(contentValues.getAsString(BaseIdentifiableObjectModel.Columns.LAST_UPDATED)).isEqualTo(m.lastUpdatedStr()); - } - - public static void testNameableModelContentValues(ContentValues contentValues, BaseNameableObjectModel m) { - testIdentifiableModelContentValues(contentValues, m); - assertThat(contentValues.getAsString(BaseNameableObjectModel.Columns.SHORT_NAME)).isEqualTo(m.shortName()); - assertThat(contentValues.getAsString(BaseNameableObjectModel.Columns.DISPLAY_SHORT_NAME)).isEqualTo(m.displayShortName()); - assertThat(contentValues.getAsString(BaseNameableObjectModel.Columns.DESCRIPTION)).isEqualTo(m.description()); - assertThat(contentValues.getAsString(BaseNameableObjectModel.Columns.DISPLAY_DESCRIPTION)).isEqualTo(m.displayDescription()); - } -} diff --git a/core/src/androidTest/resources/db_version_5.sql b/core/src/androidTest/resources/db_version_5.sql new file mode 100644 index 0000000000..474266d0f1 --- /dev/null +++ b/core/src/androidTest/resources/db_version_5.sql @@ -0,0 +1,47 @@ +CREATE TABLE UserRoleProgramLink (_id INTEGER PRIMARY KEY AUTOINCREMENT,userRole TEXT NOT NULL,program TEXT NOT NULL, FOREIGN KEY (userRole) REFERENCES UserRole (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (program) REFERENCES Program (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, UNIQUE (userRole, program)); +CREATE TABLE UserRole (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT); +CREATE TABLE UserOrganisationUnit (_id INTEGER PRIMARY KEY AUTOINCREMENT,user TEXT NOT NULL,organisationUnit TEXT NOT NULL,organisationUnitScope TEXT NOT NULL, FOREIGN KEY (user) REFERENCES User (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (organisationUnit) REFERENCES OrganisationUnit (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,UNIQUE (user, organisationUnit, organisationUnitScope)); +CREATE TABLE UserCredentials (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,username TEXT,user TEXT NOT NULL UNIQUE, FOREIGN KEY (user) REFERENCES User (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED ); +CREATE TABLE User (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,birthday TEXT,education TEXT,gender TEXT,jobTitle TEXT,surname TEXT,firstName TEXT,introduction TEXT,employer TEXT,interests TEXT,languages TEXT,email TEXT,phoneNumber TEXT,nationality TEXT); +CREATE TABLE TrackedEntityInstance (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,created TEXT,lastUpdated TEXT,createdAtClient TEXT,lastUpdatedAtClient TEXT,organisationUnit TEXT NOT NULL,trackedEntity TEXT NOT NULL,state TEXT, FOREIGN KEY (organisationUnit) REFERENCES OrganisationUnit (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED FOREIGN KEY (trackedEntity) REFERENCES TrackedEntity (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE TrackedEntityDataValue (_id INTEGER PRIMARY KEY AUTOINCREMENT,event TEXT NOT NULL,dataElement TEXT NOT NULL,storedBy TEXT,value TEXT,created TEXT,lastUpdated TEXT,providedElsewhere INTEGER, FOREIGN KEY (dataElement) REFERENCES DataElement (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (event) REFERENCES Event (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE TrackedEntityAttributeValue (_id INTEGER PRIMARY KEY AUTOINCREMENT,created TEXT,lastUpdated TEXT,value TEXT,trackedEntityAttribute TEXT NOT NULL,trackedEntityInstance TEXT NOT NULL, FOREIGN KEY (trackedEntityAttribute) REFERENCES TrackedEntityAttribute (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (trackedEntityInstance) REFERENCES TrackedEntityInstance (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE TrackedEntityAttribute (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,shortName TEXT,displayShortName TEXT,description TEXT,displayDescription TEXT,pattern TEXT,sortOrderInListNoProgram INTEGER,optionSet TEXT,valueType TEXT,expression TEXT,searchScope TEXT,programScope INTEGER,displayInListNoProgram INTEGER,generated INTEGER,displayOnVisitSchedule INTEGER,orgunitScope INTEGER,uniqueProperty INTEGER,inherit INTEGER, FOREIGN KEY (optionSet) REFERENCES OptionSet (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE TrackedEntity (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,shortName TEXT,displayShortName TEXT,description TEXT,displayDescription TEXT); +CREATE TABLE SystemInfo (_id INTEGER PRIMARY KEY AUTOINCREMENT, serverDate TEXT,dateFormat TEXT,version TEXT,contextPath TEXT); +CREATE TABLE Resource (_id INTEGER PRIMARY KEY AUTOINCREMENT,resourceType TEXT NOT NULL,lastSynced TEXT); +CREATE TABLE RelationshipType (_id INTEGER PRIMARY KEY AUTOINCREMENT, uid TEXT NOT NULL UNIQUE, code TEXT, name TEXT, displayName TEXT, created TEXT, lastUpdated TEXT, bIsToA TEXT, AIsToB TEXT ); +CREATE TABLE Relationship (_id INTEGER PRIMARY KEY AUTOINCREMENT,trackedEntityInstanceA TEXT NOT NULL,trackedEntityInstanceB TEXT NOT NULL,relationshipType TEXT NOT NULL, FOREIGN KEY (relationshipType) REFERENCES RelationshipType (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED FOREIGN KEY (trackedEntityInstanceA) REFERENCES TrackedEntityInstance (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED FOREIGN KEY (trackedEntityInstanceB) REFERENCES TrackedEntityInstance (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE ProgramTrackedEntityAttribute (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,shortName TEXT,displayShortName TEXT,description TEXT,displayDescription TEXT,mandatory INTEGER,trackedEntityAttribute TEXT NOT NULL,allowFutureDate INTEGER,displayInList INTEGER,sortOrder INTEGER,program TEXT NOT NULL, FOREIGN KEY (trackedEntityAttribute) REFERENCES TrackedEntityAttribute (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (program) REFERENCES Program (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE ProgramStageSectionProgramIndicatorLinkTable (_id INTEGER PRIMARY KEY AUTOINCREMENT,programStageSection TEXT NOT NULL,programIndicator TEXT NOT NULL, FOREIGN KEY (programStageSection) REFERENCES ProgramStageSection (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (programIndicator) REFERENCES ProgramIndicator (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, UNIQUE (programStageSection, programIndicator)); +CREATE TABLE ProgramStageSection (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,sortOrder INTEGER,programStage TEXT NOT NULL, FOREIGN KEY ( programStage) REFERENCES ProgramStage (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE ProgramStageDataElement (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,displayInReports INTEGER,compulsory INTEGER,allowProvidedElsewhere INTEGER,sortOrder INTEGER,allowFutureDate INTEGER,dataElement TEXT NOT NULL,programStage TEXT NOT NULL,programStageSection TEXT, FOREIGN KEY (programStage) REFERENCES ProgramStage (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (dataElement) REFERENCES DataElement (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (programStageSection) REFERENCES ProgramStageSection (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE ProgramStage (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,executionDateLabel TEXT,allowGenerateNextVisit INTEGER,validCompleteOnly INTEGER,reportDateToUse TEXT,openAfterEnrollment INTEGER,repeatable INTEGER,captureCoordinates INTEGER,formType TEXT,displayGenerateEventBox INTEGER,generatedByEnrollmentDate INTEGER,autoGenerateEvent INTEGER,sortOrder INTEGER,hideDueDate INTEGER,blockEntryForm INTEGER,minDaysFromStart INTEGER,standardInterval INTEGER,program TEXT NOT NULL, FOREIGN KEY ( program) REFERENCES Program (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE ProgramRuleVariable (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,useCodeForOptionSet INTEGER,program TEXT NOT NULL,programStage TEXT,dataElement TEXT,trackedEntityAttribute TEXT,programRuleVariableSourceType TEXT, FOREIGN KEY (program) REFERENCES Program (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (programStage) REFERENCES ProgramStage (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (trackedEntityAttribute) REFERENCES TrackedEntityAttribute(uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (dataElement) REFERENCES DataElement (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE ProgramRuleAction (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,data TEXT,content TEXT,location TEXT,trackedEntityAttribute TEXT,programIndicator TEXT,programStageSection TEXT,programRuleActionType TEXT,programStage TEXT,dataElement TEXT,programRule TEXT NOT NULL, FOREIGN KEY (programRule) REFERENCES ProgramRule (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (trackedEntityAttribute) REFERENCES TrackedEntityAttribute (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (programIndicator) REFERENCES ProgramIndicator (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (programStageSection) REFERENCES ProgramStageSection (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (programStage) REFERENCES ProgramStage (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (dataElement) REFERENCES DataElement (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE ProgramRule (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,priority INTEGER,condition TEXT,program TEXT NOT NULL,programStage TEXT, FOREIGN KEY (program) REFERENCES Program (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (programStage) REFERENCES ProgramStage (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE ProgramIndicator (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,shortName TEXT,displayShortName TEXT,description TEXT,displayDescription TEXT,displayInForm INTEGER,expression TEXT,dimensionItem TEXT,filter TEXT,decimals INTEGER,program TEXT NOT NULL, FOREIGN KEY (program) REFERENCES Program (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED ); +CREATE TABLE Program (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,shortName TEXT,displayShortName TEXT,description TEXT,displayDescription TEXT,version INTEGER,onlyEnrollOnce INTEGER,enrollmentDateLabel TEXT,displayIncidentDate INTEGER,incidentDateLabel TEXT,registration INTEGER,selectEnrollmentDatesInFuture INTEGER,dataEntryMethod INTEGER,ignoreOverdueEvents INTEGER,relationshipFromA INTEGER,selectIncidentDatesInFuture INTEGER,captureCoordinates INTEGER,useFirstStageDuringRegistration INTEGER,displayFrontPageList INTEGER,programType TEXT,relationshipType TEXT,relationshipText TEXT,relatedProgram TEXT,trackedEntity TEXT,categoryCombo TEXT, FOREIGN KEY (relationshipType) REFERENCES RelationshipType (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (trackedEntity) REFERENCES TrackedEntity (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (categoryCombo) REFERENCES CategoryCombo (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE OrganisationUnitProgramLink (_id INTEGER PRIMARY KEY AUTOINCREMENT,organisationUnit TEXT NOT NULL,program TEXT NOT NULL, FOREIGN KEY (organisationUnit) REFERENCES OrganisationUnit (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (program) REFERENCES Program (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, UNIQUE (organisationUnit, program)); +CREATE TABLE OrganisationUnit (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,shortName TEXT,displayShortName TEXT,description TEXT,displayDescription TEXT,path TEXT,openingDate TEXT,closedDate TEXT,level INTEGER,parent TEXT); +CREATE TABLE OptionSet (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,version INTEGER,valueType TEXT); +CREATE TABLE Option (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,optionSet TEXT NOT NULL, FOREIGN KEY (optionSet) REFERENCES OptionSet (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED ); +CREATE TABLE Event (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,enrollment TEXT,created TEXT,lastUpdated TEXT,createdAtClient TEXT,lastUpdatedAtClient TEXT,status TEXT,latitude TEXT,longitude TEXT,program TEXT NOT NULL,programStage TEXT NOT NULL,organisationUnit TEXT NOT NULL,eventDate TEXT,completedDate TEXT,dueDate TEXT,state TEXT, attributeCategoryOptions TEXT, attributeOptionCombo TEXT, trackedEntityInstance TEXT, FOREIGN KEY (program) REFERENCES Program (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (programStage) REFERENCES ProgramStage (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,FOREIGN KEY (enrollment) REFERENCES Enrollment (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (organisationUnit) REFERENCES OrganisationUnit (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE Enrollment (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,created TEXT,lastUpdated TEXT,createdAtClient TEXT,lastUpdatedAtClient TEXT,organisationUnit TEXT NOT NULL,program TEXT NOT NULL,enrollmentDate TEXT,incidentDate TEXT,followup INTEGER,status TEXT,trackedEntityInstance TEXT NOT NULL,latitude TEXT,longitude TEXT,state TEXT, FOREIGN KEY (organisationUnit) REFERENCES OrganisationUnit (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (program) REFERENCES Program (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (trackedEntityInstance) REFERENCES TrackedEntityInstance (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE DataElement (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,shortName TEXT,displayShortName TEXT,description TEXT,displayDescription TEXT,valueType TEXT,zeroIsSignificant INTEGER,aggregationType TEXT,formName TEXT,numberType TEXT,domainType TEXT,dimension TEXT,displayFormName TEXT,optionSet TEXT,categoryCombo TEXT, FOREIGN KEY ( optionSet) REFERENCES OptionSet (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (categoryCombo) REFERENCES CategoryCombo (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE Constant (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,value TEXT); +CREATE TABLE Configuration (_id INTEGER PRIMARY KEY AUTOINCREMENT,serverUrl TEXT NOT NULL UNIQUE); +CREATE TABLE CategoryCategoryOptionLink (_id INTEGER PRIMARY KEY AUTOINCREMENT,category TEXT NOT NULL,categoryOption TEXT NOT NULL, FOREIGN KEY (category) REFERENCES Category (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (categoryOption) REFERENCES CategoryOption (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,UNIQUE (category, categoryOption)); +CREATE TABLE CategoryOptionComboCategoryLink (_id INTEGER PRIMARY KEY AUTOINCREMENT,categoryOptionCombo TEXT NOT NULL,category TEXT NOT NULL, FOREIGN KEY (categoryOptionCombo) REFERENCES CategoryOptionCombo (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (category) REFERENCES CategoryOption (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,UNIQUE (categoryOptionCombo, category)); +CREATE TABLE CategoryOptionCombo (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT, categoryCombo TEXT, FOREIGN KEY (categoryCombo) REFERENCES CategoryCombo (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED ); +CREATE TABLE CategoryOption (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT); +CREATE TABLE CategoryCategoryComboLink (_id INTEGER PRIMARY KEY AUTOINCREMENT,category TEXT NOT NULL,categoryCombo TEXT NOT NULL, FOREIGN KEY (category) REFERENCES Category (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (categoryCombo) REFERENCES CategoryCombo (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,UNIQUE (category, categoryCombo)); +CREATE TABLE CategoryCombo (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT, isDefault INTEGER); +CREATE TABLE Category (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,dataDimensionType TEXT); +CREATE TABLE AuthenticatedUser (_id INTEGER PRIMARY KEY AUTOINCREMENT,user TEXT NOT NULL UNIQUE,credentials TEXT NOT NULL, FOREIGN KEY (user) REFERENCES User (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE DataSet (_id INTEGER PRIMARY KEY AUTOINCREMENT, uid TEXT NOT NULL UNIQUE, code TEXT, name TEXT, displayName TEXT, created TEXT, lastUpdated TEXT, shortName TEXT, displayShortName TEXT, description TEXT, displayDescription TEXT, periodType TEXT,categoryCombo TEXT NOT NULL,mobile INTEGER,version INTEGER,expiryDays INTEGER,timelyDays INTEGER,notifyCompletingUser INTEGER,openFuturePeriods INTEGER,fieldCombinationRequired INTEGER,validCompleteOnly INTEGER,noValueRequiresComment INTEGER,skipOffline INTEGER,dataElementDecoration INTEGER,renderAsTabs INTEGER,renderHorizontally INTEGER, FOREIGN KEY ( categoryCombo) REFERENCES CategoryCombo (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE DataSetDataElementLink (_id INTEGER PRIMARY KEY AUTOINCREMENT, dataSet TEXT NOT NULL,dataElement TEXT NOT NULL, FOREIGN KEY (dataSet) REFERENCES DataSet (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (dataElement) REFERENCES DataElement (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, UNIQUE (dataSet, dataElement)); +CREATE TABLE DataSetOrganisationUnitLink (_id INTEGER PRIMARY KEY AUTOINCREMENT, dataSet TEXT NOT NULL,organisationUnit TEXT NOT NULL, FOREIGN KEY (dataSet) REFERENCES DataSet (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (organisationUnit) REFERENCES OrganisationUnit (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, UNIQUE (dataSet, organisationUnit)); +CREATE TABLE Indicator (_id INTEGER PRIMARY KEY AUTOINCREMENT, uid TEXT NOT NULL UNIQUE, code TEXT, name TEXT, displayName TEXT, created TEXT, lastUpdated TEXT, shortName TEXT, displayShortName TEXT, description TEXT, displayDescription TEXT, annualized INTEGER,indicatorType TEXT,numerator TEXT,numeratorDescription TEXT,denominator TEXT,denominatorDescription TEXT,url TEXT, FOREIGN KEY ( indicatorType) REFERENCES IndicatorType (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE IndicatorType (_id INTEGER PRIMARY KEY AUTOINCREMENT, uid TEXT NOT NULL UNIQUE, code TEXT, name TEXT, displayName TEXT, created TEXT, lastUpdated TEXT, shortName TEXT, displayShortName TEXT, description TEXT, displayDescription TEXT, number INTEGER,factor INTEGER); +CREATE TABLE DataSetIndicatorLink (_id INTEGER PRIMARY KEY AUTOINCREMENT, dataSet TEXT NOT NULL,indicator TEXT NOT NULL, FOREIGN KEY (dataSet) REFERENCES DataSet (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (indicator) REFERENCES Indicator (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, UNIQUE (dataSet, indicator)); diff --git a/core/src/androidTest/resources/db_version_6.sql b/core/src/androidTest/resources/db_version_6.sql new file mode 100644 index 0000000000..3300c41933 --- /dev/null +++ b/core/src/androidTest/resources/db_version_6.sql @@ -0,0 +1,49 @@ +CREATE TABLE UserRoleProgramLink (_id INTEGER PRIMARY KEY AUTOINCREMENT,userRole TEXT NOT NULL,program TEXT NOT NULL, FOREIGN KEY (userRole) REFERENCES UserRole (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (program) REFERENCES Program (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, UNIQUE (userRole, program)); +CREATE TABLE UserRole (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT); +CREATE TABLE UserOrganisationUnit (_id INTEGER PRIMARY KEY AUTOINCREMENT,user TEXT NOT NULL,organisationUnit TEXT NOT NULL,organisationUnitScope TEXT NOT NULL, FOREIGN KEY (user) REFERENCES User (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (organisationUnit) REFERENCES OrganisationUnit (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,UNIQUE (user, organisationUnit, organisationUnitScope)); +CREATE TABLE UserCredentials (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,username TEXT,user TEXT NOT NULL UNIQUE, FOREIGN KEY (user) REFERENCES User (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED ); +CREATE TABLE User (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,birthday TEXT,education TEXT,gender TEXT,jobTitle TEXT,surname TEXT,firstName TEXT,introduction TEXT,employer TEXT,interests TEXT,languages TEXT,email TEXT,phoneNumber TEXT,nationality TEXT); +CREATE TABLE TrackedEntityInstance (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,created TEXT,lastUpdated TEXT,createdAtClient TEXT,lastUpdatedAtClient TEXT,organisationUnit TEXT NOT NULL,trackedEntity TEXT NOT NULL,state TEXT, FOREIGN KEY (organisationUnit) REFERENCES OrganisationUnit (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED FOREIGN KEY (trackedEntity) REFERENCES TrackedEntity (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE TrackedEntityDataValue (_id INTEGER PRIMARY KEY AUTOINCREMENT,event TEXT NOT NULL,dataElement TEXT NOT NULL,storedBy TEXT,value TEXT,created TEXT,lastUpdated TEXT,providedElsewhere INTEGER, FOREIGN KEY (dataElement) REFERENCES DataElement (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (event) REFERENCES Event (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE TrackedEntityAttributeValue (_id INTEGER PRIMARY KEY AUTOINCREMENT,created TEXT,lastUpdated TEXT,value TEXT,trackedEntityAttribute TEXT NOT NULL,trackedEntityInstance TEXT NOT NULL, FOREIGN KEY (trackedEntityAttribute) REFERENCES TrackedEntityAttribute (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (trackedEntityInstance) REFERENCES TrackedEntityInstance (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE TrackedEntityAttribute (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,shortName TEXT,displayShortName TEXT,description TEXT,displayDescription TEXT,pattern TEXT,sortOrderInListNoProgram INTEGER,optionSet TEXT,valueType TEXT,expression TEXT,searchScope TEXT,programScope INTEGER,displayInListNoProgram INTEGER,generated INTEGER,displayOnVisitSchedule INTEGER,orgunitScope INTEGER,uniqueProperty INTEGER,inherit INTEGER, FOREIGN KEY (optionSet) REFERENCES OptionSet (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE TrackedEntity (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,shortName TEXT,displayShortName TEXT,description TEXT,displayDescription TEXT); +CREATE TABLE SystemInfo (_id INTEGER PRIMARY KEY AUTOINCREMENT, serverDate TEXT,dateFormat TEXT,version TEXT,contextPath TEXT); +CREATE TABLE Resource (_id INTEGER PRIMARY KEY AUTOINCREMENT,resourceType TEXT NOT NULL,lastSynced TEXT); +CREATE TABLE RelationshipType (_id INTEGER PRIMARY KEY AUTOINCREMENT, uid TEXT NOT NULL UNIQUE, code TEXT, name TEXT, displayName TEXT, created TEXT, lastUpdated TEXT, bIsToA TEXT, AIsToB TEXT ); +CREATE TABLE Relationship (_id INTEGER PRIMARY KEY AUTOINCREMENT,trackedEntityInstanceA TEXT NOT NULL,trackedEntityInstanceB TEXT NOT NULL,relationshipType TEXT NOT NULL, FOREIGN KEY (relationshipType) REFERENCES RelationshipType (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED FOREIGN KEY (trackedEntityInstanceA) REFERENCES TrackedEntityInstance (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED FOREIGN KEY (trackedEntityInstanceB) REFERENCES TrackedEntityInstance (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE ProgramTrackedEntityAttribute (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,shortName TEXT,displayShortName TEXT,description TEXT,displayDescription TEXT,mandatory INTEGER,trackedEntityAttribute TEXT NOT NULL,allowFutureDate INTEGER,displayInList INTEGER,sortOrder INTEGER,program TEXT NOT NULL, FOREIGN KEY (trackedEntityAttribute) REFERENCES TrackedEntityAttribute (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (program) REFERENCES Program (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE ProgramStageSectionProgramIndicatorLinkTable (_id INTEGER PRIMARY KEY AUTOINCREMENT,programStageSection TEXT NOT NULL,programIndicator TEXT NOT NULL, FOREIGN KEY (programStageSection) REFERENCES ProgramStageSection (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (programIndicator) REFERENCES ProgramIndicator (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, UNIQUE (programStageSection, programIndicator)); +CREATE TABLE ProgramStageSection (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,sortOrder INTEGER,programStage TEXT NOT NULL, FOREIGN KEY ( programStage) REFERENCES ProgramStage (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE ProgramStageDataElement (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,displayInReports INTEGER,compulsory INTEGER,allowProvidedElsewhere INTEGER,sortOrder INTEGER,allowFutureDate INTEGER,dataElement TEXT NOT NULL,programStage TEXT NOT NULL,programStageSection TEXT, FOREIGN KEY (programStage) REFERENCES ProgramStage (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (dataElement) REFERENCES DataElement (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (programStageSection) REFERENCES ProgramStageSection (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE ProgramStage (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,executionDateLabel TEXT,allowGenerateNextVisit INTEGER,validCompleteOnly INTEGER,reportDateToUse TEXT,openAfterEnrollment INTEGER,repeatable INTEGER,captureCoordinates INTEGER,formType TEXT,displayGenerateEventBox INTEGER,generatedByEnrollmentDate INTEGER,autoGenerateEvent INTEGER,sortOrder INTEGER,hideDueDate INTEGER,blockEntryForm INTEGER,minDaysFromStart INTEGER,standardInterval INTEGER,program TEXT NOT NULL, FOREIGN KEY ( program) REFERENCES Program (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE ProgramRuleVariable (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,useCodeForOptionSet INTEGER,program TEXT NOT NULL,programStage TEXT,dataElement TEXT,trackedEntityAttribute TEXT,programRuleVariableSourceType TEXT, FOREIGN KEY (program) REFERENCES Program (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (programStage) REFERENCES ProgramStage (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (trackedEntityAttribute) REFERENCES TrackedEntityAttribute(uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (dataElement) REFERENCES DataElement (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE ProgramRuleAction (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,data TEXT,content TEXT,location TEXT,trackedEntityAttribute TEXT,programIndicator TEXT,programStageSection TEXT,programRuleActionType TEXT,programStage TEXT,dataElement TEXT,programRule TEXT NOT NULL, FOREIGN KEY (programRule) REFERENCES ProgramRule (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (trackedEntityAttribute) REFERENCES TrackedEntityAttribute (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (programIndicator) REFERENCES ProgramIndicator (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (programStageSection) REFERENCES ProgramStageSection (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (programStage) REFERENCES ProgramStage (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (dataElement) REFERENCES DataElement (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE ProgramRule (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,priority INTEGER,condition TEXT,program TEXT NOT NULL,programStage TEXT, FOREIGN KEY (program) REFERENCES Program (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (programStage) REFERENCES ProgramStage (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE ProgramIndicator (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,shortName TEXT,displayShortName TEXT,description TEXT,displayDescription TEXT,displayInForm INTEGER,expression TEXT,dimensionItem TEXT,filter TEXT,decimals INTEGER,program TEXT NOT NULL, FOREIGN KEY (program) REFERENCES Program (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED ); +CREATE TABLE Program (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,shortName TEXT,displayShortName TEXT,description TEXT,displayDescription TEXT,version INTEGER,onlyEnrollOnce INTEGER,enrollmentDateLabel TEXT,displayIncidentDate INTEGER,incidentDateLabel TEXT,registration INTEGER,selectEnrollmentDatesInFuture INTEGER,dataEntryMethod INTEGER,ignoreOverdueEvents INTEGER,relationshipFromA INTEGER,selectIncidentDatesInFuture INTEGER,captureCoordinates INTEGER,useFirstStageDuringRegistration INTEGER,displayFrontPageList INTEGER,programType TEXT,relationshipType TEXT,relationshipText TEXT,relatedProgram TEXT,trackedEntity TEXT,categoryCombo TEXT, FOREIGN KEY (relationshipType) REFERENCES RelationshipType (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (trackedEntity) REFERENCES TrackedEntity (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (categoryCombo) REFERENCES CategoryCombo (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE OrganisationUnitProgramLink (_id INTEGER PRIMARY KEY AUTOINCREMENT,organisationUnit TEXT NOT NULL,program TEXT NOT NULL, FOREIGN KEY (organisationUnit) REFERENCES OrganisationUnit (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (program) REFERENCES Program (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, UNIQUE (organisationUnit, program)); +CREATE TABLE OrganisationUnit (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,shortName TEXT,displayShortName TEXT,description TEXT,displayDescription TEXT,path TEXT,openingDate TEXT,closedDate TEXT,level INTEGER,parent TEXT); +CREATE TABLE OptionSet (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,version INTEGER,valueType TEXT); +CREATE TABLE Option (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,optionSet TEXT NOT NULL, FOREIGN KEY (optionSet) REFERENCES OptionSet (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED ); +CREATE TABLE Event (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,enrollment TEXT,created TEXT,lastUpdated TEXT,createdAtClient TEXT,lastUpdatedAtClient TEXT,status TEXT,latitude TEXT,longitude TEXT,program TEXT NOT NULL,programStage TEXT NOT NULL,organisationUnit TEXT NOT NULL,eventDate TEXT,completedDate TEXT,dueDate TEXT,state TEXT, attributeCategoryOptions TEXT, attributeOptionCombo TEXT, trackedEntityInstance TEXT, FOREIGN KEY (program) REFERENCES Program (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (programStage) REFERENCES ProgramStage (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,FOREIGN KEY (enrollment) REFERENCES Enrollment (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (organisationUnit) REFERENCES OrganisationUnit (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE Enrollment (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,created TEXT,lastUpdated TEXT,createdAtClient TEXT,lastUpdatedAtClient TEXT,organisationUnit TEXT NOT NULL,program TEXT NOT NULL,enrollmentDate TEXT,incidentDate TEXT,followup INTEGER,status TEXT,trackedEntityInstance TEXT NOT NULL,latitude TEXT,longitude TEXT,state TEXT, FOREIGN KEY (organisationUnit) REFERENCES OrganisationUnit (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (program) REFERENCES Program (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (trackedEntityInstance) REFERENCES TrackedEntityInstance (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE DataElement (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,shortName TEXT,displayShortName TEXT,description TEXT,displayDescription TEXT,valueType TEXT,zeroIsSignificant INTEGER,aggregationType TEXT,formName TEXT,numberType TEXT,domainType TEXT,dimension TEXT,displayFormName TEXT,optionSet TEXT,categoryCombo TEXT, FOREIGN KEY ( optionSet) REFERENCES OptionSet (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (categoryCombo) REFERENCES CategoryCombo (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE Constant (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,value TEXT); +CREATE TABLE Configuration (_id INTEGER PRIMARY KEY AUTOINCREMENT,serverUrl TEXT NOT NULL UNIQUE); +CREATE TABLE CategoryCategoryOptionLink (_id INTEGER PRIMARY KEY AUTOINCREMENT,category TEXT NOT NULL,categoryOption TEXT NOT NULL, FOREIGN KEY (category) REFERENCES Category (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (categoryOption) REFERENCES CategoryOption (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,UNIQUE (category, categoryOption)); +CREATE TABLE CategoryOptionComboCategoryLink (_id INTEGER PRIMARY KEY AUTOINCREMENT,categoryOptionCombo TEXT NOT NULL,category TEXT NOT NULL, FOREIGN KEY (categoryOptionCombo) REFERENCES CategoryOptionCombo (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (category) REFERENCES CategoryOption (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,UNIQUE (categoryOptionCombo, category)); +CREATE TABLE CategoryOptionCombo (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT, categoryCombo TEXT, FOREIGN KEY (categoryCombo) REFERENCES CategoryCombo (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED ); +CREATE TABLE CategoryOption (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT); +CREATE TABLE CategoryCategoryComboLink (_id INTEGER PRIMARY KEY AUTOINCREMENT,category TEXT NOT NULL,categoryCombo TEXT NOT NULL, FOREIGN KEY (category) REFERENCES Category (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (categoryCombo) REFERENCES CategoryCombo (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,UNIQUE (category, categoryCombo)); +CREATE TABLE CategoryCombo (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT, isDefault INTEGER); +CREATE TABLE Category (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,dataDimensionType TEXT); +CREATE TABLE AuthenticatedUser (_id INTEGER PRIMARY KEY AUTOINCREMENT,user TEXT NOT NULL UNIQUE,credentials TEXT NOT NULL, FOREIGN KEY (user) REFERENCES User (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE DataSet (_id INTEGER PRIMARY KEY AUTOINCREMENT, uid TEXT NOT NULL UNIQUE, code TEXT, name TEXT, displayName TEXT, created TEXT, lastUpdated TEXT, shortName TEXT, displayShortName TEXT, description TEXT, displayDescription TEXT, periodType TEXT,categoryCombo TEXT NOT NULL,mobile INTEGER,version INTEGER,expiryDays INTEGER,timelyDays INTEGER,notifyCompletingUser INTEGER,openFuturePeriods INTEGER,fieldCombinationRequired INTEGER,validCompleteOnly INTEGER,noValueRequiresComment INTEGER,skipOffline INTEGER,dataElementDecoration INTEGER,renderAsTabs INTEGER,renderHorizontally INTEGER, FOREIGN KEY ( categoryCombo) REFERENCES CategoryCombo (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE DataSetDataElementLink (_id INTEGER PRIMARY KEY AUTOINCREMENT, dataSet TEXT NOT NULL,dataElement TEXT NOT NULL, FOREIGN KEY (dataSet) REFERENCES DataSet (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (dataElement) REFERENCES DataElement (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, UNIQUE (dataSet, dataElement)); +CREATE TABLE DataSetOrganisationUnitLink (_id INTEGER PRIMARY KEY AUTOINCREMENT, dataSet TEXT NOT NULL,organisationUnit TEXT NOT NULL, FOREIGN KEY (dataSet) REFERENCES DataSet (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (organisationUnit) REFERENCES OrganisationUnit (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, UNIQUE (dataSet, organisationUnit)); +CREATE TABLE Indicator (_id INTEGER PRIMARY KEY AUTOINCREMENT, uid TEXT NOT NULL UNIQUE, code TEXT, name TEXT, displayName TEXT, created TEXT, lastUpdated TEXT, shortName TEXT, displayShortName TEXT, description TEXT, displayDescription TEXT, annualized INTEGER,indicatorType TEXT,numerator TEXT,numeratorDescription TEXT,denominator TEXT,denominatorDescription TEXT,url TEXT, FOREIGN KEY ( indicatorType) REFERENCES IndicatorType (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE IndicatorType (_id INTEGER PRIMARY KEY AUTOINCREMENT, uid TEXT NOT NULL UNIQUE, code TEXT, name TEXT, displayName TEXT, created TEXT, lastUpdated TEXT, shortName TEXT, displayShortName TEXT, description TEXT, displayDescription TEXT, number INTEGER,factor INTEGER); +CREATE TABLE DataSetIndicatorLink (_id INTEGER PRIMARY KEY AUTOINCREMENT, dataSet TEXT NOT NULL,indicator TEXT NOT NULL, FOREIGN KEY (dataSet) REFERENCES DataSet (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (indicator) REFERENCES Indicator (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, UNIQUE (dataSet, indicator)); +CREATE TABLE DataValue (_id INTEGER PRIMARY KEY AUTOINCREMENT, dataElement TEXT NOT NULL,period TEXT NOT NULL,organisationUnit TEXT NOT NULL,categoryOptionCombo TEXT NOT NULL,attributeOptionCombo TEXT NOT NULL,value TEXT,storedBy TEXT,created TEXT,lastUpdated TEXT,comment TEXT,followUp INTEGER, FOREIGN KEY (dataElement) REFERENCES DataElement (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (period) REFERENCES Period (periodId) FOREIGN KEY (organisationUnit) REFERENCES OrganisationUnit (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (categoryOptionCombo) REFERENCES CategoryOptionCombo (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (attributeOptionCombo) REFERENCES CategoryOptionCombo (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, UNIQUE (dataElement, period, organisationUnit, categoryOptionCombo, attributeOptionCombo)); +CREATE TABLE Period (_id INTEGER PRIMARY KEY AUTOINCREMENT, periodId TEXT,periodType TEXT,startDate TEXT,endDate TEXT, UNIQUE (periodId)); \ No newline at end of file diff --git a/core/src/androidTest/resources/db_version_7.sql b/core/src/androidTest/resources/db_version_7.sql new file mode 100644 index 0000000000..58b3fdf16f --- /dev/null +++ b/core/src/androidTest/resources/db_version_7.sql @@ -0,0 +1,48 @@ +CREATE TABLE UserRole (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT); +CREATE TABLE UserOrganisationUnit (_id INTEGER PRIMARY KEY AUTOINCREMENT,user TEXT NOT NULL,organisationUnit TEXT NOT NULL,organisationUnitScope TEXT NOT NULL, FOREIGN KEY (user) REFERENCES User (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (organisationUnit) REFERENCES OrganisationUnit (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,UNIQUE (user, organisationUnit, organisationUnitScope)); +CREATE TABLE UserCredentials (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,username TEXT,user TEXT NOT NULL UNIQUE, FOREIGN KEY (user) REFERENCES User (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED ); +CREATE TABLE User (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,birthday TEXT,education TEXT,gender TEXT,jobTitle TEXT,surname TEXT,firstName TEXT,introduction TEXT,employer TEXT,interests TEXT,languages TEXT,email TEXT,phoneNumber TEXT,nationality TEXT); +CREATE TABLE TrackedEntityInstance (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,created TEXT,lastUpdated TEXT,createdAtClient TEXT,lastUpdatedAtClient TEXT,organisationUnit TEXT NOT NULL,trackedEntity TEXT NOT NULL,state TEXT, FOREIGN KEY (organisationUnit) REFERENCES OrganisationUnit (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED FOREIGN KEY (trackedEntity) REFERENCES TrackedEntity (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE TrackedEntityDataValue (_id INTEGER PRIMARY KEY AUTOINCREMENT,event TEXT NOT NULL,dataElement TEXT NOT NULL,storedBy TEXT,value TEXT,created TEXT,lastUpdated TEXT,providedElsewhere INTEGER, FOREIGN KEY (dataElement) REFERENCES DataElement (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (event) REFERENCES Event (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE TrackedEntityAttributeValue (_id INTEGER PRIMARY KEY AUTOINCREMENT,created TEXT,lastUpdated TEXT,value TEXT,trackedEntityAttribute TEXT NOT NULL,trackedEntityInstance TEXT NOT NULL, FOREIGN KEY (trackedEntityAttribute) REFERENCES TrackedEntityAttribute (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (trackedEntityInstance) REFERENCES TrackedEntityInstance (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE TrackedEntityAttribute (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,shortName TEXT,displayShortName TEXT,description TEXT,displayDescription TEXT,pattern TEXT,sortOrderInListNoProgram INTEGER,optionSet TEXT,valueType TEXT,expression TEXT,searchScope TEXT,programScope INTEGER,displayInListNoProgram INTEGER,generated INTEGER,displayOnVisitSchedule INTEGER,orgunitScope INTEGER,uniqueProperty INTEGER,inherit INTEGER, FOREIGN KEY (optionSet) REFERENCES OptionSet (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE TrackedEntity (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,shortName TEXT,displayShortName TEXT,description TEXT,displayDescription TEXT); +CREATE TABLE SystemInfo (_id INTEGER PRIMARY KEY AUTOINCREMENT, serverDate TEXT,dateFormat TEXT,version TEXT,contextPath TEXT); +CREATE TABLE Resource (_id INTEGER PRIMARY KEY AUTOINCREMENT,resourceType TEXT NOT NULL,lastSynced TEXT); +CREATE TABLE RelationshipType (_id INTEGER PRIMARY KEY AUTOINCREMENT, uid TEXT NOT NULL UNIQUE, code TEXT, name TEXT, displayName TEXT, created TEXT, lastUpdated TEXT, bIsToA TEXT, AIsToB TEXT ); +CREATE TABLE Relationship (_id INTEGER PRIMARY KEY AUTOINCREMENT,trackedEntityInstanceA TEXT NOT NULL,trackedEntityInstanceB TEXT NOT NULL,relationshipType TEXT NOT NULL, FOREIGN KEY (relationshipType) REFERENCES RelationshipType (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED FOREIGN KEY (trackedEntityInstanceA) REFERENCES TrackedEntityInstance (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED FOREIGN KEY (trackedEntityInstanceB) REFERENCES TrackedEntityInstance (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE ProgramTrackedEntityAttribute (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,shortName TEXT,displayShortName TEXT,description TEXT,displayDescription TEXT,mandatory INTEGER,trackedEntityAttribute TEXT NOT NULL,allowFutureDate INTEGER,displayInList INTEGER,sortOrder INTEGER,program TEXT NOT NULL, FOREIGN KEY (trackedEntityAttribute) REFERENCES TrackedEntityAttribute (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (program) REFERENCES Program (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE ProgramStageSectionProgramIndicatorLinkTable (_id INTEGER PRIMARY KEY AUTOINCREMENT,programStageSection TEXT NOT NULL,programIndicator TEXT NOT NULL, FOREIGN KEY (programStageSection) REFERENCES ProgramStageSection (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (programIndicator) REFERENCES ProgramIndicator (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, UNIQUE (programStageSection, programIndicator)); +CREATE TABLE ProgramStageSection (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,sortOrder INTEGER,programStage TEXT NOT NULL, FOREIGN KEY ( programStage) REFERENCES ProgramStage (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE ProgramStageDataElement (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,displayInReports INTEGER,compulsory INTEGER,allowProvidedElsewhere INTEGER,sortOrder INTEGER,allowFutureDate INTEGER,dataElement TEXT NOT NULL,programStage TEXT NOT NULL,programStageSection TEXT, FOREIGN KEY (programStage) REFERENCES ProgramStage (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (dataElement) REFERENCES DataElement (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (programStageSection) REFERENCES ProgramStageSection (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE ProgramStage (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,executionDateLabel TEXT,allowGenerateNextVisit INTEGER,validCompleteOnly INTEGER,reportDateToUse TEXT,openAfterEnrollment INTEGER,repeatable INTEGER,captureCoordinates INTEGER,formType TEXT,displayGenerateEventBox INTEGER,generatedByEnrollmentDate INTEGER,autoGenerateEvent INTEGER,sortOrder INTEGER,hideDueDate INTEGER,blockEntryForm INTEGER,minDaysFromStart INTEGER,standardInterval INTEGER,program TEXT NOT NULL, FOREIGN KEY ( program) REFERENCES Program (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE ProgramRuleVariable (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,useCodeForOptionSet INTEGER,program TEXT NOT NULL,programStage TEXT,dataElement TEXT,trackedEntityAttribute TEXT,programRuleVariableSourceType TEXT, FOREIGN KEY (program) REFERENCES Program (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (programStage) REFERENCES ProgramStage (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (trackedEntityAttribute) REFERENCES TrackedEntityAttribute(uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (dataElement) REFERENCES DataElement (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE ProgramRuleAction (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,data TEXT,content TEXT,location TEXT,trackedEntityAttribute TEXT,programIndicator TEXT,programStageSection TEXT,programRuleActionType TEXT,programStage TEXT,dataElement TEXT,programRule TEXT NOT NULL, FOREIGN KEY (programRule) REFERENCES ProgramRule (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (trackedEntityAttribute) REFERENCES TrackedEntityAttribute (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (programIndicator) REFERENCES ProgramIndicator (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (programStageSection) REFERENCES ProgramStageSection (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (programStage) REFERENCES ProgramStage (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (dataElement) REFERENCES DataElement (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE ProgramRule (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,priority INTEGER,condition TEXT,program TEXT NOT NULL,programStage TEXT, FOREIGN KEY (program) REFERENCES Program (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (programStage) REFERENCES ProgramStage (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE ProgramIndicator (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,shortName TEXT,displayShortName TEXT,description TEXT,displayDescription TEXT,displayInForm INTEGER,expression TEXT,dimensionItem TEXT,filter TEXT,decimals INTEGER,program TEXT NOT NULL, FOREIGN KEY (program) REFERENCES Program (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED ); +CREATE TABLE Program (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,shortName TEXT,displayShortName TEXT,description TEXT,displayDescription TEXT,version INTEGER,onlyEnrollOnce INTEGER,enrollmentDateLabel TEXT,displayIncidentDate INTEGER,incidentDateLabel TEXT,registration INTEGER,selectEnrollmentDatesInFuture INTEGER,dataEntryMethod INTEGER,ignoreOverdueEvents INTEGER,relationshipFromA INTEGER,selectIncidentDatesInFuture INTEGER,captureCoordinates INTEGER,useFirstStageDuringRegistration INTEGER,displayFrontPageList INTEGER,programType TEXT,relationshipType TEXT,relationshipText TEXT,relatedProgram TEXT,trackedEntity TEXT,categoryCombo TEXT, accessDataWrite INTEGER, FOREIGN KEY (relationshipType) REFERENCES RelationshipType (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (trackedEntity) REFERENCES TrackedEntity (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (categoryCombo) REFERENCES CategoryCombo (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE OrganisationUnitProgramLink (_id INTEGER PRIMARY KEY AUTOINCREMENT,organisationUnit TEXT NOT NULL,program TEXT NOT NULL, FOREIGN KEY (organisationUnit) REFERENCES OrganisationUnit (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (program) REFERENCES Program (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, UNIQUE (organisationUnit, program)); +CREATE TABLE OrganisationUnit (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,shortName TEXT,displayShortName TEXT,description TEXT,displayDescription TEXT,path TEXT,openingDate TEXT,closedDate TEXT,level INTEGER,parent TEXT); +CREATE TABLE OptionSet (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,version INTEGER,valueType TEXT); +CREATE TABLE Option (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,optionSet TEXT NOT NULL, FOREIGN KEY (optionSet) REFERENCES OptionSet (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED ); +CREATE TABLE Event (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,enrollment TEXT,created TEXT,lastUpdated TEXT,createdAtClient TEXT,lastUpdatedAtClient TEXT,status TEXT,latitude TEXT,longitude TEXT,program TEXT NOT NULL,programStage TEXT NOT NULL,organisationUnit TEXT NOT NULL,eventDate TEXT,completedDate TEXT,dueDate TEXT,state TEXT, attributeCategoryOptions TEXT, attributeOptionCombo TEXT, trackedEntityInstance TEXT, FOREIGN KEY (program) REFERENCES Program (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (programStage) REFERENCES ProgramStage (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,FOREIGN KEY (enrollment) REFERENCES Enrollment (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (organisationUnit) REFERENCES OrganisationUnit (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE Enrollment (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,created TEXT,lastUpdated TEXT,createdAtClient TEXT,lastUpdatedAtClient TEXT,organisationUnit TEXT NOT NULL,program TEXT NOT NULL,enrollmentDate TEXT,incidentDate TEXT,followup INTEGER,status TEXT,trackedEntityInstance TEXT NOT NULL,latitude TEXT,longitude TEXT,state TEXT, FOREIGN KEY (organisationUnit) REFERENCES OrganisationUnit (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (program) REFERENCES Program (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (trackedEntityInstance) REFERENCES TrackedEntityInstance (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE DataElement (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,shortName TEXT,displayShortName TEXT,description TEXT,displayDescription TEXT,valueType TEXT,zeroIsSignificant INTEGER,aggregationType TEXT,formName TEXT,numberType TEXT,domainType TEXT,dimension TEXT,displayFormName TEXT,optionSet TEXT,categoryCombo TEXT, FOREIGN KEY ( optionSet) REFERENCES OptionSet (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (categoryCombo) REFERENCES CategoryCombo (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE Constant (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,value TEXT); +CREATE TABLE Configuration (_id INTEGER PRIMARY KEY AUTOINCREMENT,serverUrl TEXT NOT NULL UNIQUE); +CREATE TABLE CategoryCategoryOptionLink (_id INTEGER PRIMARY KEY AUTOINCREMENT,category TEXT NOT NULL,categoryOption TEXT NOT NULL, FOREIGN KEY (category) REFERENCES Category (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (categoryOption) REFERENCES CategoryOption (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,UNIQUE (category, categoryOption)); +CREATE TABLE CategoryOptionComboCategoryLink (_id INTEGER PRIMARY KEY AUTOINCREMENT,categoryOptionCombo TEXT NOT NULL,category TEXT NOT NULL, FOREIGN KEY (categoryOptionCombo) REFERENCES CategoryOptionCombo (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (category) REFERENCES CategoryOption (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,UNIQUE (categoryOptionCombo, category)); +CREATE TABLE CategoryOptionCombo (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT, categoryCombo TEXT, FOREIGN KEY (categoryCombo) REFERENCES CategoryCombo (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED ); +CREATE TABLE CategoryOption (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT); +CREATE TABLE CategoryCategoryComboLink (_id INTEGER PRIMARY KEY AUTOINCREMENT,category TEXT NOT NULL,categoryCombo TEXT NOT NULL, FOREIGN KEY (category) REFERENCES Category (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (categoryCombo) REFERENCES CategoryCombo (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,UNIQUE (category, categoryCombo)); +CREATE TABLE CategoryCombo (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT, isDefault INTEGER); +CREATE TABLE Category (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,dataDimensionType TEXT); +CREATE TABLE AuthenticatedUser (_id INTEGER PRIMARY KEY AUTOINCREMENT,user TEXT NOT NULL UNIQUE,credentials TEXT NOT NULL, FOREIGN KEY (user) REFERENCES User (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE DataSet (_id INTEGER PRIMARY KEY AUTOINCREMENT, uid TEXT NOT NULL UNIQUE, code TEXT, name TEXT, displayName TEXT, created TEXT, lastUpdated TEXT, shortName TEXT, displayShortName TEXT, description TEXT, displayDescription TEXT, periodType TEXT,categoryCombo TEXT NOT NULL,mobile INTEGER,version INTEGER,expiryDays INTEGER,timelyDays INTEGER,notifyCompletingUser INTEGER,openFuturePeriods INTEGER,fieldCombinationRequired INTEGER,validCompleteOnly INTEGER,noValueRequiresComment INTEGER,skipOffline INTEGER,dataElementDecoration INTEGER,renderAsTabs INTEGER,renderHorizontally INTEGER, accessDataWrite INTEGER, FOREIGN KEY ( categoryCombo) REFERENCES CategoryCombo (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE DataSetDataElementLink (_id INTEGER PRIMARY KEY AUTOINCREMENT, dataSet TEXT NOT NULL,dataElement TEXT NOT NULL, FOREIGN KEY (dataSet) REFERENCES DataSet (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (dataElement) REFERENCES DataElement (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, UNIQUE (dataSet, dataElement)); +CREATE TABLE DataSetOrganisationUnitLink (_id INTEGER PRIMARY KEY AUTOINCREMENT, dataSet TEXT NOT NULL,organisationUnit TEXT NOT NULL, FOREIGN KEY (dataSet) REFERENCES DataSet (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (organisationUnit) REFERENCES OrganisationUnit (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, UNIQUE (dataSet, organisationUnit)); +CREATE TABLE Indicator (_id INTEGER PRIMARY KEY AUTOINCREMENT, uid TEXT NOT NULL UNIQUE, code TEXT, name TEXT, displayName TEXT, created TEXT, lastUpdated TEXT, shortName TEXT, displayShortName TEXT, description TEXT, displayDescription TEXT, annualized INTEGER,indicatorType TEXT,numerator TEXT,numeratorDescription TEXT,denominator TEXT,denominatorDescription TEXT,url TEXT, FOREIGN KEY ( indicatorType) REFERENCES IndicatorType (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE IndicatorType (_id INTEGER PRIMARY KEY AUTOINCREMENT, uid TEXT NOT NULL UNIQUE, code TEXT, name TEXT, displayName TEXT, created TEXT, lastUpdated TEXT, shortName TEXT, displayShortName TEXT, description TEXT, displayDescription TEXT, number INTEGER,factor INTEGER); +CREATE TABLE DataSetIndicatorLink (_id INTEGER PRIMARY KEY AUTOINCREMENT, dataSet TEXT NOT NULL,indicator TEXT NOT NULL, FOREIGN KEY (dataSet) REFERENCES DataSet (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (indicator) REFERENCES Indicator (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, UNIQUE (dataSet, indicator)); +CREATE TABLE DataValue (_id INTEGER PRIMARY KEY AUTOINCREMENT, dataElement TEXT NOT NULL,period TEXT NOT NULL,organisationUnit TEXT NOT NULL,categoryOptionCombo TEXT NOT NULL,attributeOptionCombo TEXT NOT NULL,value TEXT,storedBy TEXT,created TEXT,lastUpdated TEXT,comment TEXT,followUp INTEGER, FOREIGN KEY (dataElement) REFERENCES DataElement (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (organisationUnit) REFERENCES OrganisationUnit (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (categoryOptionCombo) REFERENCES CategoryOptionCombo (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (attributeOptionCombo) REFERENCES CategoryOptionCombo (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, UNIQUE (dataElement, period, organisationUnit, categoryOptionCombo, attributeOptionCombo)); +CREATE TABLE Period (_id INTEGER PRIMARY KEY AUTOINCREMENT, periodId TEXT,periodType TEXT,startDate TEXT,endDate TEXT, UNIQUE (periodId)); \ No newline at end of file diff --git a/core/src/androidTest/resources/db_version_8.sql b/core/src/androidTest/resources/db_version_8.sql new file mode 100644 index 0000000000..2651645a29 --- /dev/null +++ b/core/src/androidTest/resources/db_version_8.sql @@ -0,0 +1,49 @@ +CREATE TABLE UserRole (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT); +CREATE TABLE UserOrganisationUnit (_id INTEGER PRIMARY KEY AUTOINCREMENT,user TEXT NOT NULL,organisationUnit TEXT NOT NULL,organisationUnitScope TEXT NOT NULL, FOREIGN KEY (user) REFERENCES User (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (organisationUnit) REFERENCES OrganisationUnit (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,UNIQUE (user, organisationUnit, organisationUnitScope)); +CREATE TABLE UserCredentials (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,username TEXT,user TEXT NOT NULL UNIQUE, FOREIGN KEY (user) REFERENCES User (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED ); +CREATE TABLE User (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,birthday TEXT,education TEXT,gender TEXT,jobTitle TEXT,surname TEXT,firstName TEXT,introduction TEXT,employer TEXT,interests TEXT,languages TEXT,email TEXT,phoneNumber TEXT,nationality TEXT); +CREATE TABLE TrackedEntityInstance (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,created TEXT,lastUpdated TEXT,createdAtClient TEXT,lastUpdatedAtClient TEXT,organisationUnit TEXT NOT NULL,trackedEntity TEXT NOT NULL,state TEXT, FOREIGN KEY (organisationUnit) REFERENCES OrganisationUnit (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED FOREIGN KEY (trackedEntity) REFERENCES TrackedEntity (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE TrackedEntityDataValue (_id INTEGER PRIMARY KEY AUTOINCREMENT,event TEXT NOT NULL,dataElement TEXT NOT NULL,storedBy TEXT,value TEXT,created TEXT,lastUpdated TEXT,providedElsewhere INTEGER, FOREIGN KEY (dataElement) REFERENCES DataElement (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (event) REFERENCES Event (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE TrackedEntityAttributeValue (_id INTEGER PRIMARY KEY AUTOINCREMENT,created TEXT,lastUpdated TEXT,value TEXT,trackedEntityAttribute TEXT NOT NULL,trackedEntityInstance TEXT NOT NULL, FOREIGN KEY (trackedEntityAttribute) REFERENCES TrackedEntityAttribute (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (trackedEntityInstance) REFERENCES TrackedEntityInstance (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE TrackedEntityAttribute (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,shortName TEXT,displayShortName TEXT,description TEXT,displayDescription TEXT,pattern TEXT,sortOrderInListNoProgram INTEGER,optionSet TEXT,valueType TEXT,expression TEXT,searchScope TEXT,programScope INTEGER,displayInListNoProgram INTEGER,generated INTEGER,displayOnVisitSchedule INTEGER,orgunitScope INTEGER,uniqueProperty INTEGER,inherit INTEGER, FOREIGN KEY (optionSet) REFERENCES OptionSet (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE TrackedEntity (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,shortName TEXT,displayShortName TEXT,description TEXT,displayDescription TEXT); +CREATE TABLE SystemInfo (_id INTEGER PRIMARY KEY AUTOINCREMENT, serverDate TEXT,dateFormat TEXT,version TEXT,contextPath TEXT); +CREATE TABLE Resource (_id INTEGER PRIMARY KEY AUTOINCREMENT,resourceType TEXT NOT NULL,lastSynced TEXT); +CREATE TABLE RelationshipType (_id INTEGER PRIMARY KEY AUTOINCREMENT, uid TEXT NOT NULL UNIQUE, code TEXT, name TEXT, displayName TEXT, created TEXT, lastUpdated TEXT, bIsToA TEXT, AIsToB TEXT ); +CREATE TABLE Relationship (_id INTEGER PRIMARY KEY AUTOINCREMENT,trackedEntityInstanceA TEXT NOT NULL,trackedEntityInstanceB TEXT NOT NULL,relationshipType TEXT NOT NULL, FOREIGN KEY (relationshipType) REFERENCES RelationshipType (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED FOREIGN KEY (trackedEntityInstanceA) REFERENCES TrackedEntityInstance (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED FOREIGN KEY (trackedEntityInstanceB) REFERENCES TrackedEntityInstance (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE ProgramTrackedEntityAttribute (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,shortName TEXT,displayShortName TEXT,description TEXT,displayDescription TEXT,mandatory INTEGER,trackedEntityAttribute TEXT NOT NULL,allowFutureDate INTEGER,displayInList INTEGER,sortOrder INTEGER,program TEXT NOT NULL, FOREIGN KEY (trackedEntityAttribute) REFERENCES TrackedEntityAttribute (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (program) REFERENCES Program (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE ProgramStageSectionProgramIndicatorLinkTable (_id INTEGER PRIMARY KEY AUTOINCREMENT,programStageSection TEXT NOT NULL,programIndicator TEXT NOT NULL, FOREIGN KEY (programStageSection) REFERENCES ProgramStageSection (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (programIndicator) REFERENCES ProgramIndicator (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, UNIQUE (programStageSection, programIndicator)); +CREATE TABLE ProgramStageSection (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,sortOrder INTEGER,programStage TEXT NOT NULL, FOREIGN KEY ( programStage) REFERENCES ProgramStage (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE ProgramStageDataElement (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,displayInReports INTEGER,compulsory INTEGER,allowProvidedElsewhere INTEGER,sortOrder INTEGER,allowFutureDate INTEGER,dataElement TEXT NOT NULL,programStage TEXT NOT NULL,programStageSection TEXT, FOREIGN KEY (programStage) REFERENCES ProgramStage (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (dataElement) REFERENCES DataElement (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (programStageSection) REFERENCES ProgramStageSection (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE ProgramStage (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,executionDateLabel TEXT,allowGenerateNextVisit INTEGER,validCompleteOnly INTEGER,reportDateToUse TEXT,openAfterEnrollment INTEGER,repeatable INTEGER,captureCoordinates INTEGER,formType TEXT,displayGenerateEventBox INTEGER,generatedByEnrollmentDate INTEGER,autoGenerateEvent INTEGER,sortOrder INTEGER,hideDueDate INTEGER,blockEntryForm INTEGER,minDaysFromStart INTEGER,standardInterval INTEGER,program TEXT NOT NULL, FOREIGN KEY ( program) REFERENCES Program (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE ProgramRuleVariable (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,useCodeForOptionSet INTEGER,program TEXT NOT NULL,programStage TEXT,dataElement TEXT,trackedEntityAttribute TEXT,programRuleVariableSourceType TEXT, FOREIGN KEY (program) REFERENCES Program (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (programStage) REFERENCES ProgramStage (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (trackedEntityAttribute) REFERENCES TrackedEntityAttribute(uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (dataElement) REFERENCES DataElement (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE ProgramRuleAction (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,data TEXT,content TEXT,location TEXT,trackedEntityAttribute TEXT,programIndicator TEXT,programStageSection TEXT,programRuleActionType TEXT,programStage TEXT,dataElement TEXT,programRule TEXT NOT NULL, FOREIGN KEY (programRule) REFERENCES ProgramRule (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (trackedEntityAttribute) REFERENCES TrackedEntityAttribute (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (programIndicator) REFERENCES ProgramIndicator (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (programStageSection) REFERENCES ProgramStageSection (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (programStage) REFERENCES ProgramStage (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (dataElement) REFERENCES DataElement (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE ProgramRule (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,priority INTEGER,condition TEXT,program TEXT NOT NULL,programStage TEXT, FOREIGN KEY (program) REFERENCES Program (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (programStage) REFERENCES ProgramStage (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE ProgramIndicator (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,shortName TEXT,displayShortName TEXT,description TEXT,displayDescription TEXT,displayInForm INTEGER,expression TEXT,dimensionItem TEXT,filter TEXT,decimals INTEGER,program TEXT NOT NULL, FOREIGN KEY (program) REFERENCES Program (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED ); +CREATE TABLE Program (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,shortName TEXT,displayShortName TEXT,description TEXT,displayDescription TEXT,version INTEGER,onlyEnrollOnce INTEGER,enrollmentDateLabel TEXT,displayIncidentDate INTEGER,incidentDateLabel TEXT,registration INTEGER,selectEnrollmentDatesInFuture INTEGER,dataEntryMethod INTEGER,ignoreOverdueEvents INTEGER,relationshipFromA INTEGER,selectIncidentDatesInFuture INTEGER,captureCoordinates INTEGER,useFirstStageDuringRegistration INTEGER,displayFrontPageList INTEGER,programType TEXT,relationshipType TEXT,relationshipText TEXT,relatedProgram TEXT,trackedEntity TEXT,categoryCombo TEXT, accessDataWrite INTEGER, FOREIGN KEY (relationshipType) REFERENCES RelationshipType (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (trackedEntity) REFERENCES TrackedEntity (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (categoryCombo) REFERENCES CategoryCombo (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE OrganisationUnitProgramLink (_id INTEGER PRIMARY KEY AUTOINCREMENT,organisationUnit TEXT NOT NULL,program TEXT NOT NULL, FOREIGN KEY (organisationUnit) REFERENCES OrganisationUnit (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (program) REFERENCES Program (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, UNIQUE (organisationUnit, program)); +CREATE TABLE OrganisationUnit (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,shortName TEXT,displayShortName TEXT,description TEXT,displayDescription TEXT,path TEXT,openingDate TEXT,closedDate TEXT,level INTEGER,parent TEXT); +CREATE TABLE OptionSet (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,version INTEGER,valueType TEXT); +CREATE TABLE Option (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,optionSet TEXT NOT NULL, FOREIGN KEY (optionSet) REFERENCES OptionSet (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED ); +CREATE TABLE Event (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,enrollment TEXT,created TEXT,lastUpdated TEXT,createdAtClient TEXT,lastUpdatedAtClient TEXT,status TEXT,latitude TEXT,longitude TEXT,program TEXT NOT NULL,programStage TEXT NOT NULL,organisationUnit TEXT NOT NULL,eventDate TEXT,completedDate TEXT,dueDate TEXT,state TEXT, attributeCategoryOptions TEXT, attributeOptionCombo TEXT, trackedEntityInstance TEXT, FOREIGN KEY (program) REFERENCES Program (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (programStage) REFERENCES ProgramStage (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,FOREIGN KEY (enrollment) REFERENCES Enrollment (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (organisationUnit) REFERENCES OrganisationUnit (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE Enrollment (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,created TEXT,lastUpdated TEXT,createdAtClient TEXT,lastUpdatedAtClient TEXT,organisationUnit TEXT NOT NULL,program TEXT NOT NULL,enrollmentDate TEXT,incidentDate TEXT,followup INTEGER,status TEXT,trackedEntityInstance TEXT NOT NULL,latitude TEXT,longitude TEXT,state TEXT, FOREIGN KEY (organisationUnit) REFERENCES OrganisationUnit (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (program) REFERENCES Program (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (trackedEntityInstance) REFERENCES TrackedEntityInstance (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE DataElement (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,shortName TEXT,displayShortName TEXT,description TEXT,displayDescription TEXT,valueType TEXT,zeroIsSignificant INTEGER,aggregationType TEXT,formName TEXT,numberType TEXT,domainType TEXT,dimension TEXT,displayFormName TEXT,optionSet TEXT,categoryCombo TEXT, FOREIGN KEY ( optionSet) REFERENCES OptionSet (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (categoryCombo) REFERENCES CategoryCombo (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE Constant (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,value TEXT); +CREATE TABLE Configuration (_id INTEGER PRIMARY KEY AUTOINCREMENT,serverUrl TEXT NOT NULL UNIQUE); +CREATE TABLE CategoryCategoryOptionLink (_id INTEGER PRIMARY KEY AUTOINCREMENT,category TEXT NOT NULL,categoryOption TEXT NOT NULL, FOREIGN KEY (category) REFERENCES Category (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (categoryOption) REFERENCES CategoryOption (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,UNIQUE (category, categoryOption)); +CREATE TABLE CategoryOptionComboCategoryLink (_id INTEGER PRIMARY KEY AUTOINCREMENT,categoryOptionCombo TEXT NOT NULL,category TEXT NOT NULL, FOREIGN KEY (categoryOptionCombo) REFERENCES CategoryOptionCombo (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (category) REFERENCES CategoryOption (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,UNIQUE (categoryOptionCombo, category)); +CREATE TABLE CategoryOptionCombo (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT, categoryCombo TEXT, FOREIGN KEY (categoryCombo) REFERENCES CategoryCombo (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED ); +CREATE TABLE CategoryOption (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT); +CREATE TABLE CategoryCategoryComboLink (_id INTEGER PRIMARY KEY AUTOINCREMENT,category TEXT NOT NULL,categoryCombo TEXT NOT NULL, FOREIGN KEY (category) REFERENCES Category (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (categoryCombo) REFERENCES CategoryCombo (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,UNIQUE (category, categoryCombo)); +CREATE TABLE CategoryCombo (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT, isDefault INTEGER); +CREATE TABLE Category (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,dataDimensionType TEXT); +CREATE TABLE AuthenticatedUser (_id INTEGER PRIMARY KEY AUTOINCREMENT,user TEXT NOT NULL UNIQUE,credentials TEXT NOT NULL, FOREIGN KEY (user) REFERENCES User (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE DataSet (_id INTEGER PRIMARY KEY AUTOINCREMENT, uid TEXT NOT NULL UNIQUE, code TEXT, name TEXT, displayName TEXT, created TEXT, lastUpdated TEXT, shortName TEXT, displayShortName TEXT, description TEXT, displayDescription TEXT, periodType TEXT,categoryCombo TEXT NOT NULL,mobile INTEGER,version INTEGER,expiryDays INTEGER,timelyDays INTEGER,notifyCompletingUser INTEGER,openFuturePeriods INTEGER,fieldCombinationRequired INTEGER,validCompleteOnly INTEGER,noValueRequiresComment INTEGER,skipOffline INTEGER,dataElementDecoration INTEGER,renderAsTabs INTEGER,renderHorizontally INTEGER, accessDataWrite INTEGER, FOREIGN KEY ( categoryCombo) REFERENCES CategoryCombo (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE DataSetDataElementLink (_id INTEGER PRIMARY KEY AUTOINCREMENT, dataSet TEXT NOT NULL,dataElement TEXT NOT NULL, FOREIGN KEY (dataSet) REFERENCES DataSet (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (dataElement) REFERENCES DataElement (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, UNIQUE (dataSet, dataElement)); +CREATE TABLE DataSetOrganisationUnitLink (_id INTEGER PRIMARY KEY AUTOINCREMENT, dataSet TEXT NOT NULL,organisationUnit TEXT NOT NULL, FOREIGN KEY (dataSet) REFERENCES DataSet (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (organisationUnit) REFERENCES OrganisationUnit (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, UNIQUE (dataSet, organisationUnit)); +CREATE TABLE Indicator (_id INTEGER PRIMARY KEY AUTOINCREMENT, uid TEXT NOT NULL UNIQUE, code TEXT, name TEXT, displayName TEXT, created TEXT, lastUpdated TEXT, shortName TEXT, displayShortName TEXT, description TEXT, displayDescription TEXT, annualized INTEGER,indicatorType TEXT,numerator TEXT,numeratorDescription TEXT,denominator TEXT,denominatorDescription TEXT,url TEXT, FOREIGN KEY ( indicatorType) REFERENCES IndicatorType (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE IndicatorType (_id INTEGER PRIMARY KEY AUTOINCREMENT, uid TEXT NOT NULL UNIQUE, code TEXT, name TEXT, displayName TEXT, created TEXT, lastUpdated TEXT, shortName TEXT, displayShortName TEXT, description TEXT, displayDescription TEXT, number INTEGER,factor INTEGER); +CREATE TABLE DataSetIndicatorLink (_id INTEGER PRIMARY KEY AUTOINCREMENT, dataSet TEXT NOT NULL,indicator TEXT NOT NULL, FOREIGN KEY (dataSet) REFERENCES DataSet (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (indicator) REFERENCES Indicator (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, UNIQUE (dataSet, indicator)); +CREATE TABLE DataValue (_id INTEGER PRIMARY KEY AUTOINCREMENT, dataElement TEXT NOT NULL,period TEXT NOT NULL,organisationUnit TEXT NOT NULL,categoryOptionCombo TEXT NOT NULL,attributeOptionCombo TEXT NOT NULL,value TEXT,storedBy TEXT,created TEXT,lastUpdated TEXT,comment TEXT,followUp INTEGER, FOREIGN KEY (dataElement) REFERENCES DataElement (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (organisationUnit) REFERENCES OrganisationUnit (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (categoryOptionCombo) REFERENCES CategoryOptionCombo (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (attributeOptionCombo) REFERENCES CategoryOptionCombo (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, UNIQUE (dataElement, period, organisationUnit, categoryOptionCombo, attributeOptionCombo)); +CREATE TABLE Period (_id INTEGER PRIMARY KEY AUTOINCREMENT, periodId TEXT,periodType TEXT,startDate TEXT,endDate TEXT, UNIQUE (periodId)); +CREATE TABLE ObjectStyle (_id INTEGER PRIMARY KEY AUTOINCREMENT, uid TEXT,objectTable TEXT,color TEXT,icon TEXT, UNIQUE (uid)); \ No newline at end of file diff --git a/core/src/androidTest/resources/db_version_9.sql b/core/src/androidTest/resources/db_version_9.sql new file mode 100644 index 0000000000..24927f85db --- /dev/null +++ b/core/src/androidTest/resources/db_version_9.sql @@ -0,0 +1,50 @@ +CREATE TABLE UserRole (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT); +CREATE TABLE UserOrganisationUnit (_id INTEGER PRIMARY KEY AUTOINCREMENT,user TEXT NOT NULL,organisationUnit TEXT NOT NULL,organisationUnitScope TEXT NOT NULL, FOREIGN KEY (user) REFERENCES User (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (organisationUnit) REFERENCES OrganisationUnit (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,UNIQUE (user, organisationUnit, organisationUnitScope)); +CREATE TABLE UserCredentials (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,username TEXT,user TEXT NOT NULL UNIQUE, FOREIGN KEY (user) REFERENCES User (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED ); +CREATE TABLE User (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,birthday TEXT,education TEXT,gender TEXT,jobTitle TEXT,surname TEXT,firstName TEXT,introduction TEXT,employer TEXT,interests TEXT,languages TEXT,email TEXT,phoneNumber TEXT,nationality TEXT); +CREATE TABLE TrackedEntityInstance (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,created TEXT,lastUpdated TEXT,createdAtClient TEXT,lastUpdatedAtClient TEXT,organisationUnit TEXT NOT NULL,trackedEntity TEXT NOT NULL,state TEXT, FOREIGN KEY (organisationUnit) REFERENCES OrganisationUnit (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED FOREIGN KEY (trackedEntity) REFERENCES TrackedEntity (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE TrackedEntityDataValue (_id INTEGER PRIMARY KEY AUTOINCREMENT,event TEXT NOT NULL,dataElement TEXT NOT NULL,storedBy TEXT,value TEXT,created TEXT,lastUpdated TEXT,providedElsewhere INTEGER, FOREIGN KEY (dataElement) REFERENCES DataElement (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (event) REFERENCES Event (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE TrackedEntityAttributeValue (_id INTEGER PRIMARY KEY AUTOINCREMENT,created TEXT,lastUpdated TEXT,value TEXT,trackedEntityAttribute TEXT NOT NULL,trackedEntityInstance TEXT NOT NULL, FOREIGN KEY (trackedEntityAttribute) REFERENCES TrackedEntityAttribute (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (trackedEntityInstance) REFERENCES TrackedEntityInstance (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE TrackedEntityAttribute (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,shortName TEXT,displayShortName TEXT,description TEXT,displayDescription TEXT,pattern TEXT,sortOrderInListNoProgram INTEGER,optionSet TEXT,valueType TEXT,expression TEXT,searchScope TEXT,programScope INTEGER,displayInListNoProgram INTEGER,generated INTEGER,displayOnVisitSchedule INTEGER,orgunitScope INTEGER,uniqueProperty INTEGER,inherit INTEGER, FOREIGN KEY (optionSet) REFERENCES OptionSet (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE TrackedEntity (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,shortName TEXT,displayShortName TEXT,description TEXT,displayDescription TEXT); +CREATE TABLE SystemInfo (_id INTEGER PRIMARY KEY AUTOINCREMENT, serverDate TEXT,dateFormat TEXT,version TEXT,contextPath TEXT); +CREATE TABLE Resource (_id INTEGER PRIMARY KEY AUTOINCREMENT,resourceType TEXT NOT NULL,lastSynced TEXT); +CREATE TABLE RelationshipType (_id INTEGER PRIMARY KEY AUTOINCREMENT, uid TEXT NOT NULL UNIQUE, code TEXT, name TEXT, displayName TEXT, created TEXT, lastUpdated TEXT, bIsToA TEXT, AIsToB TEXT ); +CREATE TABLE Relationship (_id INTEGER PRIMARY KEY AUTOINCREMENT,trackedEntityInstanceA TEXT NOT NULL,trackedEntityInstanceB TEXT NOT NULL,relationshipType TEXT NOT NULL, FOREIGN KEY (relationshipType) REFERENCES RelationshipType (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED FOREIGN KEY (trackedEntityInstanceA) REFERENCES TrackedEntityInstance (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED FOREIGN KEY (trackedEntityInstanceB) REFERENCES TrackedEntityInstance (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE ProgramTrackedEntityAttribute (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,shortName TEXT,displayShortName TEXT,description TEXT,displayDescription TEXT,mandatory INTEGER,trackedEntityAttribute TEXT NOT NULL,allowFutureDate INTEGER,displayInList INTEGER,sortOrder INTEGER,program TEXT NOT NULL, FOREIGN KEY (trackedEntityAttribute) REFERENCES TrackedEntityAttribute (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (program) REFERENCES Program (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE ProgramStageSectionProgramIndicatorLinkTable (_id INTEGER PRIMARY KEY AUTOINCREMENT,programStageSection TEXT NOT NULL,programIndicator TEXT NOT NULL, FOREIGN KEY (programStageSection) REFERENCES ProgramStageSection (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (programIndicator) REFERENCES ProgramIndicator (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, UNIQUE (programStageSection, programIndicator)); +CREATE TABLE ProgramStageSection (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,sortOrder INTEGER,programStage TEXT NOT NULL,desktopRenderType TEXT,mobileRenderType TEXT, FOREIGN KEY ( programStage) REFERENCES ProgramStage (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE ProgramStageDataElement (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,displayInReports INTEGER,compulsory INTEGER,allowProvidedElsewhere INTEGER,sortOrder INTEGER,allowFutureDate INTEGER,dataElement TEXT NOT NULL,programStage TEXT NOT NULL,programStageSection TEXT, FOREIGN KEY (programStage) REFERENCES ProgramStage (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (dataElement) REFERENCES DataElement (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (programStageSection) REFERENCES ProgramStageSection (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE ProgramStage (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,executionDateLabel TEXT,allowGenerateNextVisit INTEGER,validCompleteOnly INTEGER,reportDateToUse TEXT,openAfterEnrollment INTEGER,repeatable INTEGER,captureCoordinates INTEGER,formType TEXT,displayGenerateEventBox INTEGER,generatedByEnrollmentDate INTEGER,autoGenerateEvent INTEGER,sortOrder INTEGER,hideDueDate INTEGER,blockEntryForm INTEGER,minDaysFromStart INTEGER,standardInterval INTEGER,program TEXT NOT NULL, FOREIGN KEY ( program) REFERENCES Program (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE ProgramRuleVariable (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,useCodeForOptionSet INTEGER,program TEXT NOT NULL,programStage TEXT,dataElement TEXT,trackedEntityAttribute TEXT,programRuleVariableSourceType TEXT, FOREIGN KEY (program) REFERENCES Program (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (programStage) REFERENCES ProgramStage (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (trackedEntityAttribute) REFERENCES TrackedEntityAttribute(uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (dataElement) REFERENCES DataElement (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE ProgramRuleAction (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,data TEXT,content TEXT,location TEXT,trackedEntityAttribute TEXT,programIndicator TEXT,programStageSection TEXT,programRuleActionType TEXT,programStage TEXT,dataElement TEXT,programRule TEXT NOT NULL, FOREIGN KEY (programRule) REFERENCES ProgramRule (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (trackedEntityAttribute) REFERENCES TrackedEntityAttribute (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (programIndicator) REFERENCES ProgramIndicator (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (programStageSection) REFERENCES ProgramStageSection (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (programStage) REFERENCES ProgramStage (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (dataElement) REFERENCES DataElement (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE ProgramRule (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,priority INTEGER,condition TEXT,program TEXT NOT NULL,programStage TEXT, FOREIGN KEY (program) REFERENCES Program (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (programStage) REFERENCES ProgramStage (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE ProgramIndicator (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,shortName TEXT,displayShortName TEXT,description TEXT,displayDescription TEXT,displayInForm INTEGER,expression TEXT,dimensionItem TEXT,filter TEXT,decimals INTEGER,program TEXT NOT NULL, FOREIGN KEY (program) REFERENCES Program (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED ); +CREATE TABLE Program (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,shortName TEXT,displayShortName TEXT,description TEXT,displayDescription TEXT,version INTEGER,onlyEnrollOnce INTEGER,enrollmentDateLabel TEXT,displayIncidentDate INTEGER,incidentDateLabel TEXT,registration INTEGER,selectEnrollmentDatesInFuture INTEGER,dataEntryMethod INTEGER,ignoreOverdueEvents INTEGER,relationshipFromA INTEGER,selectIncidentDatesInFuture INTEGER,captureCoordinates INTEGER,useFirstStageDuringRegistration INTEGER,displayFrontPageList INTEGER,programType TEXT,relationshipType TEXT,relationshipText TEXT,relatedProgram TEXT,trackedEntity TEXT,categoryCombo TEXT, accessDataWrite INTEGER, FOREIGN KEY (relationshipType) REFERENCES RelationshipType (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (trackedEntity) REFERENCES TrackedEntity (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (categoryCombo) REFERENCES CategoryCombo (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE OrganisationUnitProgramLink (_id INTEGER PRIMARY KEY AUTOINCREMENT,organisationUnit TEXT NOT NULL,program TEXT NOT NULL, FOREIGN KEY (organisationUnit) REFERENCES OrganisationUnit (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (program) REFERENCES Program (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, UNIQUE (organisationUnit, program)); +CREATE TABLE OrganisationUnit (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,shortName TEXT,displayShortName TEXT,description TEXT,displayDescription TEXT,path TEXT,openingDate TEXT,closedDate TEXT,level INTEGER,parent TEXT); +CREATE TABLE OptionSet (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,version INTEGER,valueType TEXT); +CREATE TABLE Option (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,optionSet TEXT NOT NULL, FOREIGN KEY (optionSet) REFERENCES OptionSet (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED ); +CREATE TABLE Event (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,enrollment TEXT,created TEXT,lastUpdated TEXT,createdAtClient TEXT,lastUpdatedAtClient TEXT,status TEXT,latitude TEXT,longitude TEXT,program TEXT NOT NULL,programStage TEXT NOT NULL,organisationUnit TEXT NOT NULL,eventDate TEXT,completedDate TEXT,dueDate TEXT,state TEXT, attributeCategoryOptions TEXT, attributeOptionCombo TEXT, trackedEntityInstance TEXT, FOREIGN KEY (program) REFERENCES Program (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (programStage) REFERENCES ProgramStage (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,FOREIGN KEY (enrollment) REFERENCES Enrollment (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (organisationUnit) REFERENCES OrganisationUnit (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE Enrollment (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,created TEXT,lastUpdated TEXT,createdAtClient TEXT,lastUpdatedAtClient TEXT,organisationUnit TEXT NOT NULL,program TEXT NOT NULL,enrollmentDate TEXT,incidentDate TEXT,followup INTEGER,status TEXT,trackedEntityInstance TEXT NOT NULL,latitude TEXT,longitude TEXT,state TEXT, FOREIGN KEY (organisationUnit) REFERENCES OrganisationUnit (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (program) REFERENCES Program (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (trackedEntityInstance) REFERENCES TrackedEntityInstance (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE DataElement (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,shortName TEXT,displayShortName TEXT,description TEXT,displayDescription TEXT,valueType TEXT,zeroIsSignificant INTEGER,aggregationType TEXT,formName TEXT,numberType TEXT,domainType TEXT,dimension TEXT,displayFormName TEXT,optionSet TEXT,categoryCombo TEXT, FOREIGN KEY ( optionSet) REFERENCES OptionSet (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (categoryCombo) REFERENCES CategoryCombo (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE Constant (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,value TEXT); +CREATE TABLE Configuration (_id INTEGER PRIMARY KEY AUTOINCREMENT,serverUrl TEXT NOT NULL UNIQUE); +CREATE TABLE CategoryCategoryOptionLink (_id INTEGER PRIMARY KEY AUTOINCREMENT,category TEXT NOT NULL,categoryOption TEXT NOT NULL, FOREIGN KEY (category) REFERENCES Category (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (categoryOption) REFERENCES CategoryOption (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,UNIQUE (category, categoryOption)); +CREATE TABLE CategoryOptionComboCategoryLink (_id INTEGER PRIMARY KEY AUTOINCREMENT,categoryOptionCombo TEXT NOT NULL,category TEXT NOT NULL, FOREIGN KEY (categoryOptionCombo) REFERENCES CategoryOptionCombo (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (category) REFERENCES CategoryOption (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,UNIQUE (categoryOptionCombo, category)); +CREATE TABLE CategoryOptionCombo (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT, categoryCombo TEXT, FOREIGN KEY (categoryCombo) REFERENCES CategoryCombo (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED ); +CREATE TABLE CategoryOption (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT); +CREATE TABLE CategoryCategoryComboLink (_id INTEGER PRIMARY KEY AUTOINCREMENT,category TEXT NOT NULL,categoryCombo TEXT NOT NULL, FOREIGN KEY (category) REFERENCES Category (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (categoryCombo) REFERENCES CategoryCombo (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,UNIQUE (category, categoryCombo)); +CREATE TABLE CategoryCombo (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT, isDefault INTEGER); +CREATE TABLE Category (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,dataDimensionType TEXT); +CREATE TABLE AuthenticatedUser (_id INTEGER PRIMARY KEY AUTOINCREMENT,user TEXT NOT NULL UNIQUE,credentials TEXT NOT NULL, FOREIGN KEY (user) REFERENCES User (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE DataSet (_id INTEGER PRIMARY KEY AUTOINCREMENT, uid TEXT NOT NULL UNIQUE, code TEXT, name TEXT, displayName TEXT, created TEXT, lastUpdated TEXT, shortName TEXT, displayShortName TEXT, description TEXT, displayDescription TEXT, periodType TEXT,categoryCombo TEXT NOT NULL,mobile INTEGER,version INTEGER,expiryDays INTEGER,timelyDays INTEGER,notifyCompletingUser INTEGER,openFuturePeriods INTEGER,fieldCombinationRequired INTEGER,validCompleteOnly INTEGER,noValueRequiresComment INTEGER,skipOffline INTEGER,dataElementDecoration INTEGER,renderAsTabs INTEGER,renderHorizontally INTEGER, accessDataWrite INTEGER, FOREIGN KEY ( categoryCombo) REFERENCES CategoryCombo (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE DataSetDataElementLink (_id INTEGER PRIMARY KEY AUTOINCREMENT, dataSet TEXT NOT NULL,dataElement TEXT NOT NULL, FOREIGN KEY (dataSet) REFERENCES DataSet (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (dataElement) REFERENCES DataElement (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, UNIQUE (dataSet, dataElement)); +CREATE TABLE DataSetOrganisationUnitLink (_id INTEGER PRIMARY KEY AUTOINCREMENT, dataSet TEXT NOT NULL,organisationUnit TEXT NOT NULL, FOREIGN KEY (dataSet) REFERENCES DataSet (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (organisationUnit) REFERENCES OrganisationUnit (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, UNIQUE (dataSet, organisationUnit)); +CREATE TABLE Indicator (_id INTEGER PRIMARY KEY AUTOINCREMENT, uid TEXT NOT NULL UNIQUE, code TEXT, name TEXT, displayName TEXT, created TEXT, lastUpdated TEXT, shortName TEXT, displayShortName TEXT, description TEXT, displayDescription TEXT, annualized INTEGER,indicatorType TEXT,numerator TEXT,numeratorDescription TEXT,denominator TEXT,denominatorDescription TEXT,url TEXT, FOREIGN KEY ( indicatorType) REFERENCES IndicatorType (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE IndicatorType (_id INTEGER PRIMARY KEY AUTOINCREMENT, uid TEXT NOT NULL UNIQUE, code TEXT, name TEXT, displayName TEXT, created TEXT, lastUpdated TEXT, shortName TEXT, displayShortName TEXT, description TEXT, displayDescription TEXT, number INTEGER,factor INTEGER); +CREATE TABLE DataSetIndicatorLink (_id INTEGER PRIMARY KEY AUTOINCREMENT, dataSet TEXT NOT NULL,indicator TEXT NOT NULL, FOREIGN KEY (dataSet) REFERENCES DataSet (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (indicator) REFERENCES Indicator (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, UNIQUE (dataSet, indicator)); +CREATE TABLE DataValue (_id INTEGER PRIMARY KEY AUTOINCREMENT, dataElement TEXT NOT NULL,period TEXT NOT NULL,organisationUnit TEXT NOT NULL,categoryOptionCombo TEXT NOT NULL,attributeOptionCombo TEXT NOT NULL,value TEXT,storedBy TEXT,created TEXT,lastUpdated TEXT,comment TEXT,followUp INTEGER, FOREIGN KEY (dataElement) REFERENCES DataElement (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (organisationUnit) REFERENCES OrganisationUnit (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (categoryOptionCombo) REFERENCES CategoryOptionCombo (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (attributeOptionCombo) REFERENCES CategoryOptionCombo (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, UNIQUE (dataElement, period, organisationUnit, categoryOptionCombo, attributeOptionCombo)); +CREATE TABLE Period (_id INTEGER PRIMARY KEY AUTOINCREMENT, periodId TEXT,periodType TEXT,startDate TEXT,endDate TEXT, UNIQUE (periodId)); +CREATE TABLE ObjectStyle (_id INTEGER PRIMARY KEY AUTOINCREMENT, uid TEXT,objectTable TEXT,color TEXT,icon TEXT, UNIQUE (uid)); +CREATE TABLE ValueTypeDeviceRendering (_id INTEGER PRIMARY KEY AUTOINCREMENT, uid TEXT,objectTable TEXT,deviceType TEXT,type TEXT,min INTEGER,max INTEGER,step INTEGER,decimalPoints INTEGER, UNIQUE (uid, deviceType)); \ No newline at end of file diff --git a/core/src/androidTest/resources/migrations/real_migrations/5.yaml b/core/src/androidTest/resources/migrations/real_migrations/5.yaml new file mode 100644 index 0000000000..a3ffa72038 --- /dev/null +++ b/core/src/androidTest/resources/migrations/real_migrations/5.yaml @@ -0,0 +1,4 @@ +up: + - CREATE TABLE Indicator (_id INTEGER PRIMARY KEY AUTOINCREMENT, uid TEXT NOT NULL UNIQUE, code TEXT, name TEXT, displayName TEXT, created TEXT, lastUpdated TEXT, shortName TEXT, displayShortName TEXT, description TEXT, displayDescription TEXT, annualized INTEGER,indicatorType TEXT,numerator TEXT,numeratorDescription TEXT,denominator TEXT,denominatorDescription TEXT,url TEXT, FOREIGN KEY ( indicatorType) REFERENCES IndicatorType (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); + - CREATE TABLE IndicatorType (_id INTEGER PRIMARY KEY AUTOINCREMENT, uid TEXT NOT NULL UNIQUE, code TEXT, name TEXT, displayName TEXT, created TEXT, lastUpdated TEXT, shortName TEXT, displayShortName TEXT, description TEXT, displayDescription TEXT, number INTEGER,factor INTEGER); + - CREATE TABLE DataSetIndicatorLink (_id INTEGER PRIMARY KEY AUTOINCREMENT, dataSet TEXT NOT NULL,indicator TEXT NOT NULL, FOREIGN KEY (dataSet) REFERENCES DataSet (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (indicator) REFERENCES Indicator (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, UNIQUE (dataSet, indicator)); \ No newline at end of file diff --git a/core/src/androidTest/resources/migrations/real_migrations/6.yaml b/core/src/androidTest/resources/migrations/real_migrations/6.yaml new file mode 100644 index 0000000000..e7746e66e9 --- /dev/null +++ b/core/src/androidTest/resources/migrations/real_migrations/6.yaml @@ -0,0 +1,3 @@ +up: + - CREATE TABLE DataValue (_id INTEGER PRIMARY KEY AUTOINCREMENT, dataElement TEXT NOT NULL,period TEXT NOT NULL,organisationUnit TEXT NOT NULL,categoryOptionCombo TEXT NOT NULL,attributeOptionCombo TEXT NOT NULL,value TEXT,storedBy TEXT,created TEXT,lastUpdated TEXT,comment TEXT,followUp INTEGER, FOREIGN KEY (dataElement) REFERENCES DataElement (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (period) REFERENCES Period (periodId) FOREIGN KEY (organisationUnit) REFERENCES OrganisationUnit (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (categoryOptionCombo) REFERENCES CategoryOptionCombo (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (attributeOptionCombo) REFERENCES CategoryOptionCombo (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, UNIQUE (dataElement, period, organisationUnit, categoryOptionCombo, attributeOptionCombo)); + - CREATE TABLE Period (_id INTEGER PRIMARY KEY AUTOINCREMENT, periodId TEXT,periodType TEXT,startDate TEXT,endDate TEXT, UNIQUE (periodId)); \ No newline at end of file diff --git a/core/src/androidTest/resources/migrations/real_migrations/7.yaml b/core/src/androidTest/resources/migrations/real_migrations/7.yaml new file mode 100644 index 0000000000..6ea6bab85e --- /dev/null +++ b/core/src/androidTest/resources/migrations/real_migrations/7.yaml @@ -0,0 +1,6 @@ +up: + - DROP TABLE IF EXISTS UserRoleProgramLink; + - DROP TABLE IF EXISTS Program; + - DROP TABLE IF EXISTS DataSet; + - CREATE TABLE Program (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,shortName TEXT,displayShortName TEXT,description TEXT,displayDescription TEXT,version INTEGER,onlyEnrollOnce INTEGER,enrollmentDateLabel TEXT,displayIncidentDate INTEGER,incidentDateLabel TEXT,registration INTEGER,selectEnrollmentDatesInFuture INTEGER,dataEntryMethod INTEGER,ignoreOverdueEvents INTEGER,relationshipFromA INTEGER,selectIncidentDatesInFuture INTEGER,captureCoordinates INTEGER,useFirstStageDuringRegistration INTEGER,displayFrontPageList INTEGER,programType TEXT,relationshipType TEXT,relationshipText TEXT,relatedProgram TEXT,trackedEntity TEXT,categoryCombo TEXT, accessDataWrite INTEGER, FOREIGN KEY (relationshipType) REFERENCES RelationshipType (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (trackedEntity) REFERENCES TrackedEntity (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (categoryCombo) REFERENCES CategoryCombo (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); + - CREATE TABLE DataSet (_id INTEGER PRIMARY KEY AUTOINCREMENT, uid TEXT NOT NULL UNIQUE, code TEXT, name TEXT, displayName TEXT, created TEXT, lastUpdated TEXT, shortName TEXT, displayShortName TEXT, description TEXT, displayDescription TEXT, periodType TEXT,categoryCombo TEXT NOT NULL,mobile INTEGER,version INTEGER,expiryDays INTEGER,timelyDays INTEGER,notifyCompletingUser INTEGER,openFuturePeriods INTEGER,fieldCombinationRequired INTEGER,validCompleteOnly INTEGER,noValueRequiresComment INTEGER,skipOffline INTEGER,dataElementDecoration INTEGER,renderAsTabs INTEGER,renderHorizontally INTEGER, accessDataWrite INTEGER, FOREIGN KEY ( categoryCombo) REFERENCES CategoryCombo (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); \ No newline at end of file diff --git a/core/src/androidTest/resources/migrations/real_migrations/8.yaml b/core/src/androidTest/resources/migrations/real_migrations/8.yaml new file mode 100644 index 0000000000..6c1f344590 --- /dev/null +++ b/core/src/androidTest/resources/migrations/real_migrations/8.yaml @@ -0,0 +1,2 @@ +up: + - CREATE TABLE ObjectStyle (_id INTEGER PRIMARY KEY AUTOINCREMENT, uid TEXT,objectTable TEXT,color TEXT,icon TEXT, UNIQUE (uid)); \ No newline at end of file diff --git a/core/src/androidTest/resources/migrations/real_migrations/9.yaml b/core/src/androidTest/resources/migrations/real_migrations/9.yaml new file mode 100644 index 0000000000..0fd52dddba --- /dev/null +++ b/core/src/androidTest/resources/migrations/real_migrations/9.yaml @@ -0,0 +1,4 @@ +up: + - DROP TABLE IF EXISTS ProgramStageSection; + - CREATE TABLE ProgramStageSection (_id INTEGER PRIMARY KEY AUTOINCREMENT,uid TEXT NOT NULL UNIQUE,code TEXT,name TEXT,displayName TEXT,created TEXT,lastUpdated TEXT,sortOrder INTEGER,programStage TEXT NOT NULL,desktopRenderType TEXT,mobileRenderType TEXT, FOREIGN KEY ( programStage) REFERENCES ProgramStage (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); + - CREATE TABLE ValueTypeDeviceRendering (_id INTEGER PRIMARY KEY AUTOINCREMENT, uid TEXT,objectTable TEXT,deviceType TEXT,type TEXT,min INTEGER,max INTEGER,step INTEGER,decimalPoints INTEGER, UNIQUE (uid, deviceType)); \ No newline at end of file diff --git a/core/src/main/assets/data_sets_with_access.json b/core/src/main/assets/data_sets_with_access.json new file mode 100644 index 0000000000..ad43f324a4 --- /dev/null +++ b/core/src/main/assets/data_sets_with_access.json @@ -0,0 +1,12 @@ +{ + "dataSets": [ + { + "id": "lyLU2wR22tC", + "access": { + "data": { + "read": true + } + } + } + ] +} \ No newline at end of file diff --git a/core/src/main/assets/programs_with_access.json b/core/src/main/assets/programs_with_access.json new file mode 100644 index 0000000000..6533ae0b22 --- /dev/null +++ b/core/src/main/assets/programs_with_access.json @@ -0,0 +1,92 @@ +{ + "programs": [ + { + "id": "lxAQ7Zs9VYR", + "access": { + "data": { + "read": true + } + } + }, + { + "id": "IpHINAT79UW", + "access": { + "data": { + "read": true + } + } + }, + { + "id": "kla3mAPgvCH", + "access": { + "data": { + "read": true + } + } + }, + { + "id": "q04UBOqq3rp", + "access": { + "data": { + "read": true + } + } + }, + { + "id": "eBAyeGv0exc", + "access": { + "data": { + "read": true + } + } + }, + { + "id": "VBqh0ynB2wv", + "access": { + "data": { + "read": true + } + } + }, + { + "id": "bMcwwoVnbSR", + "access": { + "data": { + "read": true + } + } + }, + { + "id": "uy2gU8kT1jF", + "access": { + "data": { + "read": true + } + } + }, + { + "id": "fDd25txQckK", + "access": { + "data": { + "read": true + } + } + }, + { + "id": "ur1Edk5Oe2n", + "access": { + "data": { + "read": true + } + } + }, + { + "id": "WSGAb5XwJ3Y", + "access": { + "data": { + "read": true + } + } + } + ] +} \ No newline at end of file diff --git a/core/src/main/java/org/hisp/dhis/android/core/D2.java b/core/src/main/java/org/hisp/dhis/android/core/D2.java index 6e049ad7c1..5beebd4737 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/D2.java +++ b/core/src/main/java/org/hisp/dhis/android/core/D2.java @@ -34,6 +34,7 @@ import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; +import org.hisp.dhis.android.core.calls.AggregatedDataCall; import org.hisp.dhis.android.core.calls.Call; import org.hisp.dhis.android.core.calls.MetadataCall; import org.hisp.dhis.android.core.calls.SingleDataCall; @@ -64,10 +65,21 @@ import org.hisp.dhis.android.core.category.CategoryStoreImpl; import org.hisp.dhis.android.core.common.BaseIdentifiableObject; import org.hisp.dhis.android.core.common.DeletableStore; +import org.hisp.dhis.android.core.common.DictionaryTableHandler; +import org.hisp.dhis.android.core.common.GenericCallData; import org.hisp.dhis.android.core.common.GenericHandler; import org.hisp.dhis.android.core.common.IdentifiableObjectStore; import org.hisp.dhis.android.core.common.ObjectStore; +import org.hisp.dhis.android.core.common.ObjectStyle; +import org.hisp.dhis.android.core.common.ObjectStyleHandler; +import org.hisp.dhis.android.core.common.ObjectStyleModel; +import org.hisp.dhis.android.core.common.ObjectStyleStore; +import org.hisp.dhis.android.core.common.ObjectWithoutUidStore; import org.hisp.dhis.android.core.common.Payload; +import org.hisp.dhis.android.core.common.ValueTypeDeviceRenderingModel; +import org.hisp.dhis.android.core.common.ValueTypeDeviceRenderingStore; +import org.hisp.dhis.android.core.common.ValueTypeRendering; +import org.hisp.dhis.android.core.common.ValueTypeRenderingHandler; import org.hisp.dhis.android.core.configuration.ConfigurationModel; import org.hisp.dhis.android.core.data.api.FieldsConverterFactory; import org.hisp.dhis.android.core.data.api.FilterConverterFactory; @@ -83,6 +95,9 @@ import org.hisp.dhis.android.core.dataset.DataSetOrganisationUnitLinkStore; import org.hisp.dhis.android.core.dataset.DataSetParentCall; import org.hisp.dhis.android.core.dataset.DataSetStore; +import org.hisp.dhis.android.core.datavalue.DataValueEndpointCall; +import org.hisp.dhis.android.core.datavalue.DataValueModel; +import org.hisp.dhis.android.core.datavalue.DataValueStore; import org.hisp.dhis.android.core.enrollment.EnrollmentHandler; import org.hisp.dhis.android.core.enrollment.EnrollmentStore; import org.hisp.dhis.android.core.enrollment.EnrollmentStoreImpl; @@ -92,6 +107,12 @@ import org.hisp.dhis.android.core.event.EventStore; import org.hisp.dhis.android.core.event.EventStoreImpl; import org.hisp.dhis.android.core.imports.WebResponse; +import org.hisp.dhis.android.core.indicator.DataSetIndicatorLinkModel; +import org.hisp.dhis.android.core.indicator.DataSetIndicatorLinkStore; +import org.hisp.dhis.android.core.indicator.IndicatorModel; +import org.hisp.dhis.android.core.indicator.IndicatorStore; +import org.hisp.dhis.android.core.indicator.IndicatorTypeModel; +import org.hisp.dhis.android.core.indicator.IndicatorTypeStore; import org.hisp.dhis.android.core.option.OptionSetHandler; import org.hisp.dhis.android.core.option.OptionSetModel; import org.hisp.dhis.android.core.option.OptionSetService; @@ -104,6 +125,8 @@ import org.hisp.dhis.android.core.organisationunit.OrganisationUnitService; import org.hisp.dhis.android.core.organisationunit.OrganisationUnitStore; import org.hisp.dhis.android.core.organisationunit.OrganisationUnitStoreImpl; +import org.hisp.dhis.android.core.period.PeriodModel; +import org.hisp.dhis.android.core.period.PeriodStore; import org.hisp.dhis.android.core.program.ProgramIndicatorStore; import org.hisp.dhis.android.core.program.ProgramIndicatorStoreImpl; import org.hisp.dhis.android.core.program.ProgramRuleActionStore; @@ -161,8 +184,6 @@ import org.hisp.dhis.android.core.user.UserCredentialsStoreImpl; import org.hisp.dhis.android.core.user.UserOrganisationUnitLinkStore; import org.hisp.dhis.android.core.user.UserOrganisationUnitLinkStoreImpl; -import org.hisp.dhis.android.core.user.UserRoleProgramLinkStore; -import org.hisp.dhis.android.core.user.UserRoleProgramLinkStoreImpl; import org.hisp.dhis.android.core.user.UserRoleStore; import org.hisp.dhis.android.core.user.UserRoleStoreImpl; import org.hisp.dhis.android.core.user.UserService; @@ -211,7 +232,6 @@ public final class D2 { private final ResourceStore resourceStore; private final SystemInfoStore systemInfoStore; private final UserRoleStore userRoleStore; - private final UserRoleProgramLinkStore userRoleProgramLinkStore; private final ProgramStore programStore; private final TrackedEntityAttributeStore trackedEntityAttributeStore; private final ProgramTrackedEntityAttributeStore programTrackedEntityAttributeStore; @@ -249,6 +269,13 @@ public final class D2 { private final IdentifiableObjectStore dataSetStore; private final ObjectStore dataSetDataElementLinkStore; private final ObjectStore dataSetOrganisationUnitLinkStore; + private final IdentifiableObjectStore indicatorStore; + private final IdentifiableObjectStore indicatorTypeStore; + private final ObjectStore dataSetIndicatorLinkStore; + private final ObjectWithoutUidStore dataValueStore; + private final ObjectWithoutUidStore periodStore; + private final ObjectWithoutUidStore objectStyleStore; + private final ObjectWithoutUidStore valueTypeDeviceRenderingStore; //Handlers private final UserCredentialsHandler userCredentialsHandler; @@ -258,10 +285,13 @@ public final class D2 { private final CategoryHandler categoryHandler; private final CategoryComboHandler categoryComboHandler; private final OrganisationUnitHandler organisationUnitHandler; - - // handlers - private final GenericHandler dataElementHandler; + private final GenericHandler dataElementHandler; private final OptionSetHandler optionSetHandler; + private final DictionaryTableHandler styleHandler; + private final DictionaryTableHandler renderTypeHandler; + + //Generic Call Data + private final GenericCallData genericCallData; @VisibleForTesting D2(@NonNull Retrofit retrofit, @NonNull DatabaseAdapter databaseAdapter) { @@ -297,8 +327,6 @@ public final class D2 { new SystemInfoStoreImpl(databaseAdapter); this.userRoleStore = new UserRoleStoreImpl(databaseAdapter); - this.userRoleProgramLinkStore = - new UserRoleProgramLinkStoreImpl(databaseAdapter); this.programStore = new ProgramStoreImpl(databaseAdapter); this.trackedEntityAttributeStore = @@ -360,13 +388,20 @@ public final class D2 { this.dataSetStore = DataSetStore.create(databaseAdapter()); this.dataSetDataElementLinkStore = DataSetDataElementLinkStore.create(databaseAdapter()); this.dataSetOrganisationUnitLinkStore = DataSetOrganisationUnitLinkStore.create(databaseAdapter()); + this.indicatorStore = IndicatorStore.create(databaseAdapter()); + this.indicatorTypeStore = IndicatorTypeStore.create(databaseAdapter()); + this.dataSetIndicatorLinkStore = DataSetIndicatorLinkStore.create(databaseAdapter()); + this.dataValueStore = DataValueStore.create(databaseAdapter()); + this.periodStore = PeriodStore.create(databaseAdapter()); + this.objectStyleStore = ObjectStyleStore.create(databaseAdapter()); + this.valueTypeDeviceRenderingStore = ValueTypeDeviceRenderingStore.create(databaseAdapter()); //handlers userCredentialsHandler = new UserCredentialsHandler(userCredentialsStore); resourceHandler = new ResourceHandler(resourceStore); organisationUnitHandler = new OrganisationUnitHandler(organisationUnitStore, - userOrganisationUnitLinkStore, organisationUnitProgramLinkStore); + userOrganisationUnitLinkStore, organisationUnitProgramLinkStore, null); TrackedEntityDataValueHandler trackedEntityDataValueHandler = new TrackedEntityDataValueHandler(trackedEntityDataValueStore); @@ -400,6 +435,11 @@ public final class D2 { // handlers this.optionSetHandler = OptionSetHandler.create(databaseAdapter); this.dataElementHandler = DataElementHandler.create(databaseAdapter, this.optionSetHandler); + this.styleHandler = ObjectStyleHandler.create(databaseAdapter); + this.renderTypeHandler = ValueTypeRenderingHandler.create(databaseAdapter); + + // data + this.genericCallData = GenericCallData.create(databaseAdapter, new ResourceHandler(resourceStore), retrofit); } @NonNull @@ -455,7 +495,6 @@ public Callable wipeDB() { deletableStoreList.add(resourceStore); deletableStoreList.add(systemInfoStore); deletableStoreList.add(userRoleStore); - deletableStoreList.add(userRoleProgramLinkStore); deletableStoreList.add(programStore); deletableStoreList.add(trackedEntityAttributeStore); deletableStoreList.add(programTrackedEntityAttributeStore); @@ -487,6 +526,13 @@ public Callable wipeDB() { deletableStoreList.add(dataSetStore); deletableStoreList.add(dataSetDataElementLinkStore); deletableStoreList.add(dataSetOrganisationUnitLinkStore); + deletableStoreList.add(indicatorStore); + deletableStoreList.add(indicatorTypeStore); + deletableStoreList.add(dataSetIndicatorLinkStore); + deletableStoreList.add(dataValueStore); + deletableStoreList.add(periodStore); + deletableStoreList.add(objectStyleStore); + deletableStoreList.add(valueTypeDeviceRenderingStore); return new LogOutUserCallable( deletableStoreList ); @@ -498,7 +544,7 @@ public Call syncMetaData() { databaseAdapter, systemInfoService, userService, programService, organisationUnitService, trackedEntityService, optionSetService, systemInfoStore, resourceStore, userStore, - userCredentialsStore, userRoleStore, userRoleProgramLinkStore, organisationUnitStore, + userCredentialsStore, userRoleStore, organisationUnitStore, userOrganisationUnitLinkStore, programStore, trackedEntityAttributeStore, programTrackedEntityAttributeStore, programRuleVariableStore, programIndicatorStore, programStageSectionProgramIndicatorLinkStore, programRuleActionStore, @@ -509,7 +555,13 @@ public Call syncMetaData() { organisationUnitProgramLinkStore, categoryQuery, categoryService, categoryHandler, categoryComboQuery, comboService, categoryComboHandler, optionSetHandler, dataElementHandler, DataSetParentCall.FACTORY, - retrofit); + styleHandler, renderTypeHandler, retrofit); + } + + @NonNull + public Call syncAggregatedData() { + return new AggregatedDataCall(genericCallData, DataValueEndpointCall.FACTORY, dataSetStore, periodStore, + organisationUnitStore); } @NonNull diff --git a/core/src/main/java/org/hisp/dhis/android/core/calls/AggregatedDataCall.java b/core/src/main/java/org/hisp/dhis/android/core/calls/AggregatedDataCall.java new file mode 100644 index 0000000000..65e1e8369d --- /dev/null +++ b/core/src/main/java/org/hisp/dhis/android/core/calls/AggregatedDataCall.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2017, University of Oslo + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.hisp.dhis.android.core.calls; + +import android.support.annotation.NonNull; + +import org.hisp.dhis.android.core.common.GenericCallData; +import org.hisp.dhis.android.core.common.IdentifiableObjectStore; +import org.hisp.dhis.android.core.common.ObjectWithoutUidStore; +import org.hisp.dhis.android.core.dataset.DataSetModel; +import org.hisp.dhis.android.core.datavalue.DataValueEndpointCall; +import org.hisp.dhis.android.core.organisationunit.OrganisationUnit; +import org.hisp.dhis.android.core.organisationunit.OrganisationUnitStore; +import org.hisp.dhis.android.core.period.PeriodModel; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import retrofit2.Response; + +public class AggregatedDataCall extends TransactionalCall { + + private final DataValueEndpointCall.Factory dataValueCallFactory; + private final IdentifiableObjectStore dataSetStore; + private final ObjectWithoutUidStore periodStore; + private final OrganisationUnitStore organisationUnitStore; + + public AggregatedDataCall(@NonNull GenericCallData genericCallData, + @NonNull DataValueEndpointCall.Factory dataValueCallFactory, + @NonNull IdentifiableObjectStore dataSetStore, + @NonNull ObjectWithoutUidStore periodStore, + @NonNull OrganisationUnitStore organisationUnitStore) { + super(genericCallData); + this.dataValueCallFactory = dataValueCallFactory; + this.dataSetStore = dataSetStore; + this.periodStore = periodStore; + this.organisationUnitStore = organisationUnitStore; + } + + @Override + public Response callBody() throws Exception { + DataValueEndpointCall dataValueEndpointCall = dataValueCallFactory.create(data, dataSetStore.selectUids(), + selectPeriodIds(periodStore.selectAll(PeriodModel.factory)), + selectOrganisationUnitUids(organisationUnitStore.queryOrganisationUnits())); + return dataValueEndpointCall.call(); + } + + private Set selectOrganisationUnitUids(List organisationUnits) { + Set organisationUnitUids = new HashSet<>(); + + for (OrganisationUnit organisationUnit: organisationUnits) { + organisationUnitUids.add(organisationUnit.uid()); + } + return organisationUnitUids; + } + + private Set selectPeriodIds(Set periodModels) { + Set periodIds = new HashSet<>(); + + for (PeriodModel period : periodModels) { + periodIds.add(period.periodId()); + } + return periodIds; + } +} diff --git a/core/src/main/java/org/hisp/dhis/android/core/calls/MetadataCall.java b/core/src/main/java/org/hisp/dhis/android/core/calls/MetadataCall.java index 5894dfcdd4..4a1e424d7e 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/calls/MetadataCall.java +++ b/core/src/main/java/org/hisp/dhis/android/core/calls/MetadataCall.java @@ -29,28 +29,30 @@ import android.support.annotation.NonNull; -import org.hisp.dhis.android.core.common.GenericCallData; -import org.hisp.dhis.android.core.common.GenericHandler; import org.hisp.dhis.android.core.category.Category; -import org.hisp.dhis.android.core.category.CategoryComboHandler; -import org.hisp.dhis.android.core.category.CategoryEndpointCall; import org.hisp.dhis.android.core.category.CategoryCombo; import org.hisp.dhis.android.core.category.CategoryComboEndpointCall; +import org.hisp.dhis.android.core.category.CategoryComboHandler; import org.hisp.dhis.android.core.category.CategoryComboQuery; import org.hisp.dhis.android.core.category.CategoryComboService; +import org.hisp.dhis.android.core.category.CategoryEndpointCall; import org.hisp.dhis.android.core.category.CategoryHandler; import org.hisp.dhis.android.core.category.CategoryQuery; import org.hisp.dhis.android.core.category.CategoryService; import org.hisp.dhis.android.core.category.ResponseValidator; +import org.hisp.dhis.android.core.common.Access; +import org.hisp.dhis.android.core.common.GenericCallData; +import org.hisp.dhis.android.core.common.GenericHandler; +import org.hisp.dhis.android.core.common.DictionaryTableHandler; +import org.hisp.dhis.android.core.common.ObjectStyle; import org.hisp.dhis.android.core.common.Payload; +import org.hisp.dhis.android.core.common.ValueTypeRendering; import org.hisp.dhis.android.core.data.database.DatabaseAdapter; import org.hisp.dhis.android.core.data.database.Transaction; import org.hisp.dhis.android.core.dataelement.DataElement; -import org.hisp.dhis.android.core.dataelement.DataElementModel; import org.hisp.dhis.android.core.dataset.DataSetParentCall; import org.hisp.dhis.android.core.option.OptionSet; import org.hisp.dhis.android.core.option.OptionSetCall; -import org.hisp.dhis.android.core.option.OptionSetModel; import org.hisp.dhis.android.core.option.OptionSetService; import org.hisp.dhis.android.core.organisationunit.OrganisationUnit; import org.hisp.dhis.android.core.organisationunit.OrganisationUnitCall; @@ -58,6 +60,7 @@ import org.hisp.dhis.android.core.organisationunit.OrganisationUnitService; import org.hisp.dhis.android.core.organisationunit.OrganisationUnitStore; import org.hisp.dhis.android.core.program.Program; +import org.hisp.dhis.android.core.program.ProgramAccessEndpointCall; import org.hisp.dhis.android.core.program.ProgramCall; import org.hisp.dhis.android.core.program.ProgramIndicatorStore; import org.hisp.dhis.android.core.program.ProgramRuleActionStore; @@ -87,8 +90,6 @@ import org.hisp.dhis.android.core.user.UserCall; import org.hisp.dhis.android.core.user.UserCredentialsStore; import org.hisp.dhis.android.core.user.UserOrganisationUnitLinkStore; -import org.hisp.dhis.android.core.user.UserRole; -import org.hisp.dhis.android.core.user.UserRoleProgramLinkStore; import org.hisp.dhis.android.core.user.UserRoleStore; import org.hisp.dhis.android.core.user.UserService; import org.hisp.dhis.android.core.user.UserStore; @@ -102,7 +103,7 @@ import retrofit2.Retrofit; @SuppressWarnings({"PMD.ExcessiveImports", "PMD.TooManyFields", "PMD.CyclomaticComplexity", - "PMD.ModifiedCyclomaticComplexity", "PMD.StdCyclomaticComplexity"}) + "PMD.ModifiedCyclomaticComplexity", "PMD.StdCyclomaticComplexity", "PMD.ExcessiveMethodLength"}) public class MetadataCall implements Call { private final DatabaseAdapter databaseAdapter; private final SystemInfoService systemInfoService; @@ -116,7 +117,6 @@ public class MetadataCall implements Call { private final UserStore userStore; private final UserCredentialsStore userCredentialsStore; private final UserRoleStore userRoleStore; - private final UserRoleProgramLinkStore userRoleProgramLinkStore; private final OrganisationUnitStore organisationUnitStore; private final UserOrganisationUnitLinkStore userOrganisationUnitLinkStore; private final ProgramStore programStore; @@ -133,8 +133,10 @@ public class MetadataCall implements Call { private final ProgramStageStore programStageStore; private final RelationshipTypeStore relationshipStore; private final TrackedEntityStore trackedEntityStore; - private final GenericHandler optionSetHandler; - private final GenericHandler dataElementHandler; + private final GenericHandler optionSetHandler; + private final GenericHandler dataElementHandler; + private final DictionaryTableHandler styleHandler; + private final DictionaryTableHandler renderTypeHandler; private final Retrofit retrofit; private final CategoryQuery categoryQuery; @@ -161,7 +163,6 @@ public MetadataCall(@NonNull DatabaseAdapter databaseAdapter, @NonNull UserStore userStore, @NonNull UserCredentialsStore userCredentialsStore, @NonNull UserRoleStore userRoleStore, - @NonNull UserRoleProgramLinkStore userRoleProgramLinkStore, @NonNull OrganisationUnitStore organisationUnitStore, @NonNull UserOrganisationUnitLinkStore userOrganisationUnitLinkStore, @NonNull ProgramStore programStore, @@ -185,9 +186,11 @@ public MetadataCall(@NonNull DatabaseAdapter databaseAdapter, @NonNull CategoryComboQuery categoryComboQuery, @NonNull CategoryComboService categoryComboService, @NonNull CategoryComboHandler categoryComboHandler, - @NonNull GenericHandler optionSetHandler, - @NonNull GenericHandler dataElementHandler, + @NonNull GenericHandler optionSetHandler, + @NonNull GenericHandler dataElementHandler, @NonNull DataSetParentCall.Factory dataSetParentCallFactory, + @NonNull DictionaryTableHandler styleHandler, + @NonNull DictionaryTableHandler renderTypeHandler, @NonNull Retrofit retrofit ) { this.databaseAdapter = databaseAdapter; @@ -202,7 +205,6 @@ public MetadataCall(@NonNull DatabaseAdapter databaseAdapter, this.userStore = userStore; this.userCredentialsStore = userCredentialsStore; this.userRoleStore = userRoleStore; - this.userRoleProgramLinkStore = userRoleProgramLinkStore; this.organisationUnitStore = organisationUnitStore; this.userOrganisationUnitLinkStore = userOrganisationUnitLinkStore; this.programStore = programStore; @@ -229,6 +231,8 @@ public MetadataCall(@NonNull DatabaseAdapter databaseAdapter, this.optionSetHandler = optionSetHandler; this.dataElementHandler = dataElementHandler; this.dataSetParentCallFactory = dataSetParentCallFactory; + this.styleHandler = styleHandler; + this.renderTypeHandler = renderTypeHandler; this.retrofit = retrofit; } @@ -264,40 +268,41 @@ public Response call() throws Exception { GenericCallData data = GenericCallData.create(databaseAdapter, new ResourceHandler(resourceStore), retrofit); - response = new UserCall( + Response userResponse = new UserCall( userService, databaseAdapter, userStore, userCredentialsStore, userRoleStore, resourceStore, - data.serverDate(), - userRoleProgramLinkStore + data.serverDate() ).call(); + response = userResponse; if (!response.isSuccessful()) { return response; } - User user = (User) response.body(); - response = new OrganisationUnitCall( - user, organisationUnitService, databaseAdapter, organisationUnitStore, - resourceStore, data.serverDate(), userOrganisationUnitLinkStore, - organisationUnitProgramLinkStore).call(); + + response = downloadCategories(data.serverDate()); + if (!response.isSuccessful()) { return response; } - response = downloadCategories(data.serverDate()); + response = downloadCategoryCombos(data.serverDate()); if (!response.isSuccessful()) { return response; } - response = downloadCategoryCombos(data.serverDate()); + + Response> programAccessResponse = ProgramAccessEndpointCall.FACTORY + .create(data, programService).call(); + response = programAccessResponse; if (!response.isSuccessful()) { return response; } - Set programUids = getAssignedProgramUids(user); + Set programUids = getProgramUidsWithDataReadAccess(programAccessResponse.body().items()); response = new ProgramCall( programService, databaseAdapter, resourceStore, programUids, programStore, data.serverDate(), @@ -308,7 +313,7 @@ public Response call() throws Exception { programRuleStore, programStageDataElementStore, programStageSectionStore, programStageStore, relationshipStore, - dataElementHandler + dataElementHandler, styleHandler, renderTypeHandler ).call(); if (!response.isSuccessful()) { return response; @@ -324,14 +329,23 @@ public Response call() throws Exception { return response; } + User user = userResponse.body(); + Response> organisationUnitResponse = new OrganisationUnitCall( + user, organisationUnitService, databaseAdapter, organisationUnitStore, + resourceStore, data.serverDate(), userOrganisationUnitLinkStore, + organisationUnitProgramLinkStore, programUids).call(); + if (!organisationUnitResponse.isSuccessful()) { + return organisationUnitResponse; + } + Set optionSetUids = getAssignedOptionSetUids(programs); response = new OptionSetCall( data, optionSetService, optionSetHandler, optionSetUids).call(); if (!response.isSuccessful()) { return response; } - - response = dataSetParentCallFactory.create(user, data).call(); + List organisationUnits = organisationUnitResponse.body().items(); + response = dataSetParentCallFactory.create(user, data, organisationUnits).call(); if (!response.isSuccessful()) { return response; } @@ -414,53 +428,16 @@ private Set getAssignedTrackedEntityUids(List programs) { return uids; } - private Set getAssignedProgramUids(User user) { - if (user == null || user.userCredentials() == null - || user.userCredentials().userRoles() == null) { - return null; - } - + private Set getProgramUidsWithDataReadAccess(List programsWithAccess) { Set programUids = new HashSet<>(); - - getProgramUidsFromUserRoles(user, programUids); - getProgramUidsFromOrganisationUnits(user, programUids); - - return programUids; - } - - private void getProgramUidsFromOrganisationUnits(User user, Set programUids) { - List organisationUnits = user.organisationUnits(); - - if (organisationUnits != null) { - int size = organisationUnits.size(); - for (int i = 0; i < size; i++) { - OrganisationUnit organisationUnit = organisationUnits.get(i); - - int programSize = organisationUnit.programs().size(); - for (int j = 0; j < programSize; j++) { - Program program = organisationUnit.programs().get(j); - - programUids.add(program.uid()); - } + for (Program program: programsWithAccess) { + Access access = program.access(); + if (access != null && access.data().read()) { + programUids.add(program.uid()); } } - } - - private void getProgramUidsFromUserRoles(User user, Set programUids) { - List userRoles = user.userCredentials().userRoles(); - if (userRoles != null) { - int size = userRoles.size(); - for (int i = 0; i < size; i++) { - UserRole userRole = userRoles.get(i); - int programSize = userRole.programs().size(); - for (int j = 0; j < programSize; j++) { - Program program = userRole.programs().get(j); - - programUids.add(program.uid()); - } - } - } + return programUids; } private Response> downloadCategories(Date serverDate) throws Exception { diff --git a/core/src/main/java/org/hisp/dhis/android/core/calls/TrackerEntitiesDataCall.java b/core/src/main/java/org/hisp/dhis/android/core/calls/TrackerEntitiesDataCall.java index c9e31892ae..e652cfe4fe 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/calls/TrackerEntitiesDataCall.java +++ b/core/src/main/java/org/hisp/dhis/android/core/calls/TrackerEntitiesDataCall.java @@ -2,10 +2,7 @@ import android.support.annotation.NonNull; -import android.util.Log; -import org.hisp.dhis.android.core.common.Payload; -import org.hisp.dhis.android.core.data.api.Fields; import org.hisp.dhis.android.core.data.database.DatabaseAdapter; import org.hisp.dhis.android.core.data.database.Transaction; import org.hisp.dhis.android.core.organisationunit.OrganisationUnit; @@ -17,8 +14,7 @@ import org.hisp.dhis.android.core.systeminfo.SystemInfoService; import org.hisp.dhis.android.core.systeminfo.SystemInfoStore; import org.hisp.dhis.android.core.trackedentity.TeiQuery; -import org.hisp.dhis.android.core.trackedentity.TrackedEntityInstance; -import org.hisp.dhis.android.core.trackedentity.TrackedEntityInstanceEndPointCall; +import org.hisp.dhis.android.core.trackedentity.TeisEndPointCall; import org.hisp.dhis.android.core.trackedentity.TrackedEntityInstanceHandler; import org.hisp.dhis.android.core.trackedentity.TrackedEntityInstanceService; @@ -109,11 +105,9 @@ public Response call() throws Exception { transaction.end(); } } - - //TODO We may need to refactor the code here. Right now it is not very optimize. - // We need a better sync mechanism, based on? lastupdated? + private Response trackerCall(Date serverDate) throws Exception { - Response> response = null; + Response response = null; List organisationUnits = organisationUnitStore.queryOrganisationUnits(); @@ -140,28 +134,11 @@ private Response trackerCall(Date serverDate) throws Exception { .withPageLimit(pageLimit) .build(); - response = trackedEntityInstanceService.getTEIs(teiQuery.getOrgUnit(), fields(), - Boolean.TRUE, teiQuery.getPage(), teiQuery.getPageLimit()).execute(); - - if (response.isSuccessful() && response.body().items() != null) { - List trackedEntityInstances = response.body().items(); - int size = trackedEntityInstances.size(); - Response apiResponse = null; - - if (teiQuery.getPageLimit() > 0) { - size = teiQuery.getPageLimit(); - } - - for (int i = 0; i < size; i++) { - apiResponse = new TrackedEntityInstanceEndPointCall(trackedEntityInstanceService, - databaseAdapter, trackedEntityInstanceHandler, resourceHandler, serverDate, - trackedEntityInstances.get(i).uid()).call(); - - if (apiResponse == null || !apiResponse.isSuccessful()) { - Log.d(this.getClass().getSimpleName(), trackedEntityInstances.get(i).uid() + " conflict"); - } - } + response = new TeisEndPointCall(trackedEntityInstanceService, databaseAdapter, + teiQuery, trackedEntityInstanceHandler, resourceHandler, serverDate).call(); + if (!response.isSuccessful()) { + return response; } teisDownloaded = teisDownloaded + teiQuery.getPageSize(); @@ -172,15 +149,5 @@ private Response trackerCall(Date serverDate) throws Exception { return response; } - private Fields fields() { - return Fields.builder().fields( - TrackedEntityInstance.uid, TrackedEntityInstance.created, - TrackedEntityInstance.lastUpdated, - TrackedEntityInstance.organisationUnit, - TrackedEntityInstance.trackedEntity, - TrackedEntityInstance.deleted - ).build(); - } - } diff --git a/core/src/main/java/org/hisp/dhis/android/core/common/Access.java b/core/src/main/java/org/hisp/dhis/android/core/common/Access.java new file mode 100644 index 0000000000..cd417ee03d --- /dev/null +++ b/core/src/main/java/org/hisp/dhis/android/core/common/Access.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2017, University of Oslo + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.hisp.dhis.android.core.common; + +import android.support.annotation.Nullable; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.auto.value.AutoValue; + +import org.hisp.dhis.android.core.data.api.Field; +import org.hisp.dhis.android.core.data.api.NestedField; + +@AutoValue +public abstract class Access { + private static final String READ = "read"; + private static final String WRITE = "write"; + private static final String UPDATE = "update"; + private static final String DELETE = "delete"; + private static final String EXTERNALIZE = "externalize"; + private static final String MANAGE = "manage"; + private static final String DATA = "data"; + + public static final Field read = Field.create(READ); + public static final Field write = Field.create(WRITE); + public static final Field update = Field.create(UPDATE); + public static final Field delete = Field.create(DELETE); + public static final Field externalize = Field.create(EXTERNALIZE); + public static final Field manage = Field.create(MANAGE); + public static final NestedField data = NestedField.create(DATA); + + @Nullable + @JsonProperty(READ) + public abstract Boolean read(); + + @Nullable + @JsonProperty(WRITE) + public abstract Boolean write(); + + @Nullable + @JsonProperty(UPDATE) + public abstract Boolean update(); + + @Nullable + @JsonProperty(DELETE) + public abstract Boolean delete(); + + @Nullable + @JsonProperty(EXTERNALIZE) + public abstract Boolean externalize(); + + @Nullable + @JsonProperty(MANAGE) + public abstract Boolean manage(); + + @Nullable + @JsonProperty(DATA) + public abstract DataAccess data(); + + @JsonCreator + public static Access create(@JsonProperty(READ) Boolean read, + @JsonProperty(WRITE) Boolean write, + @JsonProperty(UPDATE) Boolean update, + @JsonProperty(DELETE) Boolean delete, + @JsonProperty(EXTERNALIZE) Boolean externalize, + @JsonProperty(MANAGE) Boolean manage, + @JsonProperty(DATA) DataAccess data) { + return new AutoValue_Access(read, write, update, delete, externalize, manage, data); + } +} \ No newline at end of file diff --git a/core/src/main/java/org/hisp/dhis/android/core/common/BaseEndpointCall.java b/core/src/main/java/org/hisp/dhis/android/core/common/BaseEndpointCall.java new file mode 100644 index 0000000000..6950ce036c --- /dev/null +++ b/core/src/main/java/org/hisp/dhis/android/core/common/BaseEndpointCall.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2017, University of Oslo + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.hisp.dhis.android.core.common; + +import org.hisp.dhis.android.core.calls.Call; + +import retrofit2.Response; + +public abstract class BaseEndpointCall

implements Call>> { + + private boolean isExecuted; + + @Override + public final boolean isExecuted() { + synchronized (this) { + return isExecuted; + } + } + + @Override + public final Response> call() throws Exception { + synchronized (this) { + if (isExecuted) { + throw new IllegalArgumentException("Already executed"); + } + + isExecuted = true; + } + + return callBody(); + } + + protected abstract Response> callBody() throws Exception; +} diff --git a/core/src/main/java/org/hisp/dhis/android/core/common/BaseIdentifiableObjectModel.java b/core/src/main/java/org/hisp/dhis/android/core/common/BaseIdentifiableObjectModel.java index eede07f21a..460897ba8e 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/common/BaseIdentifiableObjectModel.java +++ b/core/src/main/java/org/hisp/dhis/android/core/common/BaseIdentifiableObjectModel.java @@ -42,10 +42,9 @@ import static org.hisp.dhis.android.core.utils.StoreUtils.sqLiteBind; -@SuppressWarnings("PMD") public abstract class BaseIdentifiableObjectModel extends BaseModel implements IdentifiableObject { - public static class Columns extends BaseModel.Columns { + public abstract static class Columns extends BaseModel.Columns { public static final String UID = "uid"; public static final String CODE = "code"; public static final String NAME = "name"; diff --git a/core/src/main/java/org/hisp/dhis/android/core/common/BaseModel.java b/core/src/main/java/org/hisp/dhis/android/core/common/BaseModel.java index 6dcf5b3a7d..66d41d15b5 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/common/BaseModel.java +++ b/core/src/main/java/org/hisp/dhis/android/core/common/BaseModel.java @@ -33,10 +33,10 @@ import com.gabrielittner.auto.value.cursor.ColumnName; -@SuppressWarnings("PMD") public abstract class BaseModel implements Model { - public static class Columns { + @SuppressWarnings("PMD.AbstractClassWithoutAbstractMethod") + public abstract static class Columns { public static final String ID = BaseColumns._ID; public static String[] all() { diff --git a/core/src/main/java/org/hisp/dhis/android/core/common/BaseNameableObjectModel.java b/core/src/main/java/org/hisp/dhis/android/core/common/BaseNameableObjectModel.java index 9ec110d593..8a936c70af 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/common/BaseNameableObjectModel.java +++ b/core/src/main/java/org/hisp/dhis/android/core/common/BaseNameableObjectModel.java @@ -38,10 +38,9 @@ import static org.hisp.dhis.android.core.utils.StoreUtils.sqLiteBind; -@SuppressWarnings("PMD") public abstract class BaseNameableObjectModel extends BaseIdentifiableObjectModel implements NameableObject { - public static class Columns extends BaseIdentifiableObjectModel.Columns { + public abstract static class Columns extends BaseIdentifiableObjectModel.Columns { public static final String SHORT_NAME = "shortName"; public static final String DISPLAY_SHORT_NAME = "displayShortName"; public static final String DESCRIPTION = "description"; diff --git a/core/src/main/java/org/hisp/dhis/android/core/common/BaseQuery.java b/core/src/main/java/org/hisp/dhis/android/core/common/BaseQuery.java index bab3b73725..d3220d0248 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/common/BaseQuery.java +++ b/core/src/main/java/org/hisp/dhis/android/core/common/BaseQuery.java @@ -9,6 +9,10 @@ public abstract class BaseQuery { public abstract boolean paging(); + boolean isValid() { + return true; + } + protected static abstract class Builder { public abstract T page(int page); diff --git a/core/src/main/java/org/hisp/dhis/android/core/dataset/Period.java b/core/src/main/java/org/hisp/dhis/android/core/common/DataAccess.java similarity index 63% rename from core/src/main/java/org/hisp/dhis/android/core/dataset/Period.java rename to core/src/main/java/org/hisp/dhis/android/core/common/DataAccess.java index 76777401d8..8fe2cefcbe 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/dataset/Period.java +++ b/core/src/main/java/org/hisp/dhis/android/core/common/DataAccess.java @@ -26,7 +26,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package org.hisp.dhis.android.core.dataset; +package org.hisp.dhis.android.core.common; import android.support.annotation.Nullable; @@ -34,40 +34,31 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.google.auto.value.AutoValue; -import org.hisp.dhis.android.core.common.PeriodType; import org.hisp.dhis.android.core.data.api.Field; - -import java.util.Date; +import org.hisp.dhis.android.core.data.api.Fields; @AutoValue -public abstract class Period { - private static final String PERIOD_TYPE = "periodType"; - private static final String START_DATE = "startDate"; - private static final String END_DATE = "endDate"; +public abstract class DataAccess { + private static final String READ = "read"; + private static final String WRITE = "write"; - public static final Field periodType = Field.create(PERIOD_TYPE); - public static final Field startDate = Field.create(START_DATE); - public static final Field endDate = Field.create(END_DATE); + public static final Field read = Field.create(READ); + public static final Field write = Field.create(WRITE); - @Nullable - @JsonProperty(PERIOD_TYPE) - public abstract PeriodType periodType(); + public static final Fields allFields = Fields.builder().fields( + read, write).build(); @Nullable - @JsonProperty(START_DATE) - public abstract Date startDate(); + @JsonProperty(READ) + public abstract Boolean read(); @Nullable - @JsonProperty(END_DATE) - public abstract Date endDate(); + @JsonProperty(WRITE) + public abstract Boolean write(); @JsonCreator - public static Period create( - @JsonProperty(PERIOD_TYPE) PeriodType periodType, - @JsonProperty(START_DATE) Date startDate, - @JsonProperty(END_DATE) Date endDate) { - - return new AutoValue_Period(periodType, startDate, endDate); - + public static DataAccess create(@JsonProperty(READ) Boolean read, + @JsonProperty(WRITE) Boolean write) { + return new AutoValue_DataAccess(read, write); } } diff --git a/core/src/main/java/org/hisp/dhis/android/core/common/DictionaryTableHandler.java b/core/src/main/java/org/hisp/dhis/android/core/common/DictionaryTableHandler.java new file mode 100644 index 0000000000..fd6515d67e --- /dev/null +++ b/core/src/main/java/org/hisp/dhis/android/core/common/DictionaryTableHandler.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2017, University of Oslo + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.hisp.dhis.android.core.common; + +public interface DictionaryTableHandler

{ + void handle(P pojo, String uid, String objectTable); +} diff --git a/core/src/main/java/org/hisp/dhis/android/core/common/GenericEndpointCallImpl.java b/core/src/main/java/org/hisp/dhis/android/core/common/GenericEndpointCallImpl.java index 621150cfd0..d7299f2d4c 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/common/GenericEndpointCallImpl.java +++ b/core/src/main/java/org/hisp/dhis/android/core/common/GenericEndpointCallImpl.java @@ -34,28 +34,24 @@ import java.io.IOException; import java.util.List; -import java.util.Set; import retrofit2.Response; -public abstract class GenericEndpointCallImpl

+public abstract class GenericEndpointCallImpl implements Call>> { private final GenericCallData data; - private final GenericHandler handler; + private final GenericHandler

handler; private boolean isExecuted; private final ResourceModel.Type resourceType; - private final Set uids; - private final Integer limit; + public final Q query; - public GenericEndpointCallImpl(GenericCallData data, GenericHandler handler, - ResourceModel.Type resourceType, Set uids, - Integer limit) { + public GenericEndpointCallImpl(GenericCallData data, GenericHandler

handler, + ResourceModel.Type resourceType, Q query) { this.data = data; this.handler = handler; this.resourceType = resourceType; - this.uids = uids; - this.limit = limit; + this.query = query; } @Override @@ -75,14 +71,12 @@ public final Response> call() throws Exception { isExecuted = true; } - if (limit != null && uids.size() > MAX_UIDS) { - throw new IllegalArgumentException( - "Can't handle the amount of objects of type " + resourceType + - ": " + uids.size() + ". " + "Max size is: " + MAX_UIDS); + if (!query.isValid()) { + throw new IllegalArgumentException("Invalid query"); } String lastUpdated = data.resourceHandler().getLastUpdated(resourceType); - Response> response = getCall(uids, lastUpdated).execute(); + Response> response = getCall(query, lastUpdated).execute(); if (isValidResponse(response)) { persist(response); @@ -90,10 +84,9 @@ public final Response> call() throws Exception { return response; } - protected abstract retrofit2.Call> getCall(Set uids, - String lastUpdated) throws IOException; + protected abstract retrofit2.Call> getCall(Q query, String lastUpdated) throws IOException; - private Response> persist(Response> response) { + private void persist(Response> response) { if (response == null) { throw new RuntimeException("Trying to process call without download data"); } @@ -110,7 +103,6 @@ private Response> persist(Response> response) { transaction.end(); } } - return response; } private boolean isValidResponse(Response> response) { diff --git a/core/src/main/java/org/hisp/dhis/android/core/common/GenericHandler.java b/core/src/main/java/org/hisp/dhis/android/core/common/GenericHandler.java index 7f1b142eb9..4a84dd8d79 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/common/GenericHandler.java +++ b/core/src/main/java/org/hisp/dhis/android/core/common/GenericHandler.java @@ -29,9 +29,7 @@ import java.util.Collection; -public interface GenericHandler< - P extends BaseIdentifiableObject, - M extends BaseIdentifiableObjectModel & StatementBinder> { +public interface GenericHandler

{ void handle(P p); diff --git a/core/src/main/java/org/hisp/dhis/android/core/common/GenericHandlerBaseImpl.java b/core/src/main/java/org/hisp/dhis/android/core/common/GenericHandlerBaseImpl.java new file mode 100644 index 0000000000..a171d28d5e --- /dev/null +++ b/core/src/main/java/org/hisp/dhis/android/core/common/GenericHandlerBaseImpl.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2017, University of Oslo + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.hisp.dhis.android.core.common; + +import java.util.Collection; + +public abstract class GenericHandlerBaseImpl< + P, M extends BaseModel & StatementBinder> implements GenericHandler

{ + + @Override + public final void handle(P p) { + if (p == null) { + return; + } + deleteOrPersist(p); + } + + @Override + public final void handleMany(Collection

pCollection) { + for(P p : pCollection) { + handle(p); + } + } + + protected abstract void deleteOrPersist(P p); + + @SuppressWarnings("PMD.EmptyMethodInAbstractClassShouldBeAbstract") + protected void afterObjectPersisted(P p) { + /* Method is not abstract since empty action is the default action and we don't want it to + * be unnecessarily written in every child. + */ + } + + protected abstract M pojoToModel(P p); +} diff --git a/core/src/main/java/org/hisp/dhis/android/core/common/GenericHandlerImpl.java b/core/src/main/java/org/hisp/dhis/android/core/common/IdentifiableHandlerImpl.java similarity index 74% rename from core/src/main/java/org/hisp/dhis/android/core/common/GenericHandlerImpl.java rename to core/src/main/java/org/hisp/dhis/android/core/common/IdentifiableHandlerImpl.java index 326b732ba4..e0ecb1bb6a 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/common/GenericHandlerImpl.java +++ b/core/src/main/java/org/hisp/dhis/android/core/common/IdentifiableHandlerImpl.java @@ -27,48 +27,28 @@ */ package org.hisp.dhis.android.core.common; -import java.util.Collection; - import static org.hisp.dhis.android.core.utils.Utils.isDeleted; -public abstract class GenericHandlerImpl< +public abstract class IdentifiableHandlerImpl< P extends BaseIdentifiableObject, - M extends BaseIdentifiableObjectModel & StatementBinder> implements GenericHandler { + M extends BaseIdentifiableObjectModel & StatementBinder> extends GenericHandlerBaseImpl { private final IdentifiableObjectStore store; - public GenericHandlerImpl(IdentifiableObjectStore store) { + public IdentifiableHandlerImpl(IdentifiableObjectStore store) { this.store = store; } @Override - public final void handle(P p) { - if (p == null) { - return; - } - deleteOrPersist(p); - } - - @Override - public final void handleMany(Collection

pCollection) { - for(P p : pCollection) { - handle(p); - } - } - - private void deleteOrPersist(P p) { + protected void deleteOrPersist(P p) { M m = pojoToModel(p); - if (isDeleted(p) && m.uid() != null) { - store.delete(m.uid()); + String modelUid = m.uid(); + if (isDeleted(p) && modelUid != null) { + store.delete(modelUid); } else { store.updateOrInsert(m); } this.afterObjectPersisted(p); } - - @SuppressWarnings("PMD") - protected void afterObjectPersisted(P p) {} - - protected abstract M pojoToModel(P p); } diff --git a/core/src/main/java/org/hisp/dhis/android/core/common/IdentifiableObjectStore.java b/core/src/main/java/org/hisp/dhis/android/core/common/IdentifiableObjectStore.java index 97b2d0ce2c..82ff840f70 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/common/IdentifiableObjectStore.java +++ b/core/src/main/java/org/hisp/dhis/android/core/common/IdentifiableObjectStore.java @@ -30,6 +30,8 @@ import android.support.annotation.NonNull; +import java.util.Set; + public interface IdentifiableObjectStore extends ObjectStore { @@ -38,4 +40,6 @@ public interface IdentifiableObjectStore selectUids() throws RuntimeException; } \ No newline at end of file diff --git a/core/src/main/java/org/hisp/dhis/android/core/common/IdentifiableObjectStoreImpl.java b/core/src/main/java/org/hisp/dhis/android/core/common/IdentifiableObjectStoreImpl.java index 9fa999acd9..f72d7e0202 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/common/IdentifiableObjectStoreImpl.java +++ b/core/src/main/java/org/hisp/dhis/android/core/common/IdentifiableObjectStoreImpl.java @@ -28,10 +28,14 @@ package org.hisp.dhis.android.core.common; +import android.database.Cursor; import android.support.annotation.NonNull; import org.hisp.dhis.android.core.data.database.DatabaseAdapter; +import java.util.HashSet; +import java.util.Set; + import static org.hisp.dhis.android.core.utils.StoreUtils.sqLiteBind; import static org.hisp.dhis.android.core.utils.Utils.isNull; @@ -76,6 +80,29 @@ public final void updateOrInsert(@NonNull M m) throws RuntimeException { insert(m); } } + + @Override + public Set selectUids() throws RuntimeException { + Cursor cursor = databaseAdapter.query(statements.selectUids); + return mapObjectsWithUidFromCursor(cursor); + } + + private Set mapObjectsWithUidFromCursor(Cursor cursor) { + Set uids = new HashSet<>(cursor.getCount()); + + try { + if (cursor.getCount() > 0) { + cursor.moveToFirst(); + do { + uids.add(cursor.getString(0)); + } + while (cursor.moveToNext()); + } + } finally { + cursor.close(); + } + return uids; + } } diff --git a/core/src/main/java/org/hisp/dhis/android/core/common/ObjectStore.java b/core/src/main/java/org/hisp/dhis/android/core/common/ObjectStore.java index 5dcf439ac4..1ec2c1b3bd 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/common/ObjectStore.java +++ b/core/src/main/java/org/hisp/dhis/android/core/common/ObjectStore.java @@ -30,7 +30,11 @@ import android.support.annotation.NonNull; +import java.util.Set; + public interface ObjectStore extends DeletableStore { void insert(@NonNull M m) throws RuntimeException; + + Set selectAll(LinkModelFactory modelFactory) throws RuntimeException; } \ No newline at end of file diff --git a/core/src/main/java/org/hisp/dhis/android/core/common/ObjectStoreImpl.java b/core/src/main/java/org/hisp/dhis/android/core/common/ObjectStoreImpl.java index a2f4d7d9f9..4f4bb6028c 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/common/ObjectStoreImpl.java +++ b/core/src/main/java/org/hisp/dhis/android/core/common/ObjectStoreImpl.java @@ -28,11 +28,15 @@ package org.hisp.dhis.android.core.common; +import android.database.Cursor; import android.database.sqlite.SQLiteStatement; import android.support.annotation.NonNull; import org.hisp.dhis.android.core.data.database.DatabaseAdapter; +import java.util.HashSet; +import java.util.Set; + import static org.hisp.dhis.android.core.utils.Utils.isNull; public class ObjectStoreImpl implements ObjectStore { @@ -40,8 +44,7 @@ public class ObjectStoreImpl implements Objec protected final SQLiteStatement insertStatement; protected final SQLStatementBuilder builder; - ObjectStoreImpl(DatabaseAdapter databaseAdapter, SQLiteStatement insertStatement, - SQLStatementBuilder builder) { + ObjectStoreImpl(DatabaseAdapter databaseAdapter, SQLiteStatement insertStatement, SQLStatementBuilder builder) { this.databaseAdapter = databaseAdapter; this.insertStatement = insertStatement; this.builder = builder; @@ -71,4 +74,27 @@ protected void executeUpdateDelete(SQLiteStatement statement) throws RuntimeExce throw new RuntimeException("Unexpected number of affected rows: " + numberOfAffectedRows); } } + + @Override + public Set selectAll(@NonNull LinkModelFactory modelFactory) throws RuntimeException { + Cursor cursor = databaseAdapter.query(builder.selectAll()); + return mapObjectsFromCursor(cursor, modelFactory); + } + + private Set mapObjectsFromCursor(Cursor cursor, LinkModelFactory modelFactory) { + Set objects = new HashSet<>(cursor.getCount()); + + try { + if (cursor.getCount() > 0) { + cursor.moveToFirst(); + do { + objects.add(modelFactory.fromCursor(cursor)); + } + while (cursor.moveToNext()); + } + } finally { + cursor.close(); + } + return objects; + } } \ No newline at end of file diff --git a/core/src/main/java/org/hisp/dhis/android/core/user/UserRoleProgramLinkModel.java b/core/src/main/java/org/hisp/dhis/android/core/common/ObjectStyle.java similarity index 56% rename from core/src/main/java/org/hisp/dhis/android/core/user/UserRoleProgramLinkModel.java rename to core/src/main/java/org/hisp/dhis/android/core/common/ObjectStyle.java index 7f7dd8c3ce..082afd7cb2 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/user/UserRoleProgramLinkModel.java +++ b/core/src/main/java/org/hisp/dhis/android/core/common/ObjectStyle.java @@ -25,54 +25,47 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package org.hisp.dhis.android.core.user; -import android.content.ContentValues; -import android.database.Cursor; -import android.support.annotation.NonNull; +package org.hisp.dhis.android.core.common; + import android.support.annotation.Nullable; -import com.gabrielittner.auto.value.cursor.ColumnName; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; import com.google.auto.value.AutoValue; -import org.hisp.dhis.android.core.common.BaseModel; +import org.hisp.dhis.android.core.data.api.Field; +import org.hisp.dhis.android.core.data.api.Fields; @AutoValue -public abstract class UserRoleProgramLinkModel extends BaseModel { - public static final String TABLE = "UserRoleProgramLink"; - - public static class Columns extends BaseModel.Columns { - public static final String USER_ROLE = "userRole"; - public static final String PROGRAM = "program"; - } - - public static UserRoleProgramLinkModel create(Cursor cursor) { - return AutoValue_UserRoleProgramLinkModel.createFromCursor(cursor); - } +public abstract class ObjectStyle { + private static final String COLOR = "color"; + private static final String ICON = "icon"; - public static Builder builder() { - return new $$AutoValue_UserRoleProgramLinkModel.Builder(); - } + private static final Field color = Field.create(COLOR); + private static final Field icon = Field.create(ICON); - @NonNull - public abstract ContentValues toContentValues(); + public static final Fields allFields = Fields.builder().fields(color, icon).build(); @Nullable - @ColumnName(Columns.USER_ROLE) - public abstract String userRole(); + @JsonProperty(COLOR) + public abstract String color(); @Nullable - @ColumnName(Columns.PROGRAM) - public abstract String program(); - - - @AutoValue.Builder - public static abstract class Builder extends BaseModel.Builder { + @JsonProperty(ICON) + public abstract String icon(); - public abstract Builder userRole(@Nullable String user); + @JsonCreator + public static ObjectStyle create(@JsonProperty(COLOR) String color, + @JsonProperty(ICON) String icon) { + return new AutoValue_ObjectStyle(color, icon); + } - public abstract Builder program(@Nullable String organisationUnit); + public static String getColor(ObjectStyle objectStyle) { + return objectStyle == null ? null : objectStyle.color(); + } - public abstract UserRoleProgramLinkModel build(); + public static String getIcon(ObjectStyle objectStyle) { + return objectStyle == null ? null : objectStyle.icon(); } -} +} \ No newline at end of file diff --git a/core/src/main/java/org/hisp/dhis/android/core/common/ObjectStyleHandler.java b/core/src/main/java/org/hisp/dhis/android/core/common/ObjectStyleHandler.java new file mode 100644 index 0000000000..9e5b76dcb0 --- /dev/null +++ b/core/src/main/java/org/hisp/dhis/android/core/common/ObjectStyleHandler.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2017, University of Oslo + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.hisp.dhis.android.core.common; + +import org.hisp.dhis.android.core.data.database.DatabaseAdapter; + +public class ObjectStyleHandler implements DictionaryTableHandler { + + private final ObjectWithoutUidStore store; + + ObjectStyleHandler(ObjectWithoutUidStore store) { + this.store = store; + } + + @Override + public void handle(ObjectStyle style, String uid, String objectTable) { + if (style != null) { + ObjectStyleModel model = ObjectStyleModel.fromPojo(style, uid, objectTable); + store.updateOrInsertWhere(model); + } + } + + public static ObjectStyleHandler create(DatabaseAdapter databaseAdapter) { + return new ObjectStyleHandler(ObjectStyleStore.create(databaseAdapter)); + } +} diff --git a/core/src/main/java/org/hisp/dhis/android/core/common/ObjectStyleModel.java b/core/src/main/java/org/hisp/dhis/android/core/common/ObjectStyleModel.java new file mode 100644 index 0000000000..956cc85888 --- /dev/null +++ b/core/src/main/java/org/hisp/dhis/android/core/common/ObjectStyleModel.java @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2017, University of Oslo + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.hisp.dhis.android.core.common; + +import android.content.ContentValues; +import android.database.Cursor; +import android.database.sqlite.SQLiteStatement; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import com.gabrielittner.auto.value.cursor.ColumnName; +import com.google.auto.value.AutoValue; + +import org.hisp.dhis.android.core.utils.Utils; + +import static org.hisp.dhis.android.core.utils.StoreUtils.sqLiteBind; + +@AutoValue +public abstract class ObjectStyleModel extends BaseModel implements UpdateWhereStatementBinder { + public static final String TABLE = "ObjectStyle"; + + public abstract static class Columns extends BaseModel.Columns { + public static final String UID = BaseIdentifiableObjectModel.Columns.UID; + public static final String OBJECT_TABLE = "objectTable"; + public static final String COLOR = "color"; + public static final String ICON = "icon"; + + public static String[] all() { + return Utils.appendInNewArray(BaseModel.Columns.all(), + UID, OBJECT_TABLE, COLOR, ICON); + } + + static String[] whereUpdate() { + return new String[]{UID}; + } + } + + public static ObjectStyleModel create(Cursor cursor) { + return AutoValue_ObjectStyleModel.createFromCursor(cursor); + } + + public static final LinkModelFactory factory = new LinkModelFactory() { + @Override + public ObjectStyleModel fromCursor(Cursor cursor) { + return create(cursor); + } + }; + + public static ObjectStyleModel fromPojo(ObjectStyle objectStyle, String uid, String objectTable) { + return ObjectStyleModel.builder() + .uid(uid) + .objectTable(objectTable) + .color(objectStyle.color()) + .icon(objectStyle.icon()).build(); + } + + public static Builder builder() { + return new $$AutoValue_ObjectStyleModel.Builder(); + } + + @Nullable + @ColumnName(Columns.UID) + public abstract String uid(); + + @Nullable + @ColumnName(Columns.OBJECT_TABLE) + public abstract String objectTable(); + + @Nullable + @ColumnName(Columns.COLOR) + public abstract String color(); + + @Nullable + @ColumnName(Columns.ICON) + public abstract String icon(); + + @NonNull + public abstract ContentValues toContentValues(); + + @Override + public void bindToStatement(@NonNull SQLiteStatement sqLiteStatement) { + sqLiteBind(sqLiteStatement, 1, uid()); + sqLiteBind(sqLiteStatement, 2, objectTable()); + sqLiteBind(sqLiteStatement, 3, color()); + sqLiteBind(sqLiteStatement, 4, icon()); + } + + @Override + public void bindToUpdateWhereStatement(@NonNull SQLiteStatement sqLiteStatement) { + sqLiteBind(sqLiteStatement, 5, uid()); + } + + @AutoValue.Builder + public static abstract class Builder extends BaseModel.Builder { + public abstract Builder uid(String uid); + + public abstract Builder objectTable(String objectTable); + + public abstract Builder color(String color); + + public abstract Builder icon(String icon); + + public abstract ObjectStyleModel build(); + } +} diff --git a/core/src/main/java/org/hisp/dhis/android/core/common/ObjectStyleStore.java b/core/src/main/java/org/hisp/dhis/android/core/common/ObjectStyleStore.java new file mode 100644 index 0000000000..8ff49947da --- /dev/null +++ b/core/src/main/java/org/hisp/dhis/android/core/common/ObjectStyleStore.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2017, University of Oslo + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.hisp.dhis.android.core.common; + +import org.hisp.dhis.android.core.data.database.DatabaseAdapter; + +public final class ObjectStyleStore { + + private ObjectStyleStore() {} + + public static ObjectWithoutUidStore create(DatabaseAdapter databaseAdapter) { + return StoreFactory.objectWithoutUidStore(databaseAdapter, ObjectStyleModel.TABLE, + ObjectStyleModel.Columns.all(), ObjectStyleModel.Columns.whereUpdate()); + } +} \ No newline at end of file diff --git a/core/src/main/java/org/hisp/dhis/android/core/common/ObjectWithoutUidHandlerImpl.java b/core/src/main/java/org/hisp/dhis/android/core/common/ObjectWithoutUidHandlerImpl.java new file mode 100644 index 0000000000..98dcedfde9 --- /dev/null +++ b/core/src/main/java/org/hisp/dhis/android/core/common/ObjectWithoutUidHandlerImpl.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2017, University of Oslo + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.hisp.dhis.android.core.common; + +public abstract class ObjectWithoutUidHandlerImpl< + P, M extends BaseModel & UpdateWhereStatementBinder> extends GenericHandlerBaseImpl { + + private final ObjectWithoutUidStore store; + + public ObjectWithoutUidHandlerImpl(ObjectWithoutUidStore store) { + this.store = store; + } + + @Override + protected void deleteOrPersist(P p) { + M m = pojoToModel(p); + store.updateOrInsertWhere(m); + this.afterObjectPersisted(p); + } + +} diff --git a/core/src/main/java/org/hisp/dhis/android/core/common/SQLStatementBuilder.java b/core/src/main/java/org/hisp/dhis/android/core/common/SQLStatementBuilder.java index 8164b7d88d..1ecc47b0a7 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/common/SQLStatementBuilder.java +++ b/core/src/main/java/org/hisp/dhis/android/core/common/SQLStatementBuilder.java @@ -30,31 +30,23 @@ import org.hisp.dhis.android.core.utils.Utils; -import java.util.Arrays; - -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import static org.hisp.dhis.android.core.utils.Utils.commaAndSpaceSeparatedArrayValues; public class SQLStatementBuilder { final String tableName; public final String[] columns; private final String[] updateWhereColumns; + private final static String TEXT = " TEXT"; - @SuppressFBWarnings - @SuppressWarnings("PMD") + @SuppressWarnings("PMD.UseVarargs") SQLStatementBuilder(String tableName, String[] columns, String[] updateWhereColumns) { this.tableName = tableName; - this.columns = columns; - this.updateWhereColumns = updateWhereColumns; + this.columns = columns.clone(); + this.updateWhereColumns = updateWhereColumns.clone(); } private String commaSeparatedColumns() { - return commaSeparatedArrayValues(columns); - } - - @SuppressWarnings("PMD") - private static String commaSeparatedArrayValues(String[] values) { - String withBrackets = Arrays.toString(values); - return withBrackets.substring(1, withBrackets.length() - 1); + return commaAndSpaceSeparatedArrayValues(columns); } private String commaSeparatedInterrogationMarks() { @@ -62,20 +54,18 @@ private String commaSeparatedInterrogationMarks() { for (int i = 0; i < columns.length; i++) { array[i] = "?"; } - return commaSeparatedArrayValues(array); + return commaAndSpaceSeparatedArrayValues(array); } - @SuppressWarnings("PMD") - private String commaSeparatedColumnEqualInterrogationMark(String[] cols) { + private String commaSeparatedColumnEqualInterrogationMark(String... cols) { String[] array = new String[cols.length]; for (int i = 0; i < cols.length; i++) { array[i] = cols[i] + "=?"; } - return commaSeparatedArrayValues(array); + return commaAndSpaceSeparatedArrayValues(array); } - @SuppressWarnings("PMD") - private String andSeparatedColumnEqualInterrogationMark(String[] cols) { + private String andSeparatedColumnEqualInterrogationMark(String... cols) { return commaSeparatedColumnEqualInterrogationMark(cols) .replace(",", " AND "); } @@ -90,6 +80,14 @@ String deleteById() { " WHERE " + BaseIdentifiableObjectModel.Columns.UID + "=?;"; } + String selectUids() { + return "SELECT " + BaseIdentifiableObjectModel.Columns.UID + " FROM " + tableName; + } + + String selectAll() { + return "SELECT " + commaSeparatedColumns() + " FROM " + tableName; + } + public String update() { return "UPDATE " + tableName + " SET " + commaSeparatedColumnEqualInterrogationMark(columns) + " WHERE " + BaseIdentifiableObjectModel.Columns.UID + "=?;"; @@ -102,34 +100,34 @@ String updateWhere() { return "UPDATE " + tableName + " SET " + commaSeparatedColumnEqualInterrogationMark(columns) + " WHERE " + whereClause + ";"; } - @SuppressWarnings("PMD") + + @SuppressWarnings("PMD.UseVarargs") private static String createTableWrapper(String tableName, String[] columnsWithAttributes) { return "CREATE TABLE " + tableName + " (" + - commaSeparatedArrayValues(columnsWithAttributes) + ");"; + commaAndSpaceSeparatedArrayValues(columnsWithAttributes) + ");"; } private static String[] idColumn() { return new String[]{BaseModel.Columns.ID + " INTEGER PRIMARY KEY AUTOINCREMENT"}; } - @SuppressWarnings("PMD") private static String[] identifiableColumns() { return Utils.appendInNewArray(idColumn(), - BaseIdentifiableObjectModel.Columns.UID + " TEXT NOT NULL UNIQUE", - BaseIdentifiableObjectModel.Columns.CODE + " TEXT", - BaseIdentifiableObjectModel.Columns.NAME + " TEXT", - BaseIdentifiableObjectModel.Columns.DISPLAY_NAME + " TEXT", - BaseIdentifiableObjectModel.Columns.CREATED + " TEXT", - BaseIdentifiableObjectModel.Columns.LAST_UPDATED + " TEXT" + BaseIdentifiableObjectModel.Columns.UID + TEXT + " NOT NULL UNIQUE", + BaseIdentifiableObjectModel.Columns.CODE + TEXT, + BaseIdentifiableObjectModel.Columns.NAME + TEXT, + BaseIdentifiableObjectModel.Columns.DISPLAY_NAME + TEXT, + BaseIdentifiableObjectModel.Columns.CREATED + TEXT, + BaseIdentifiableObjectModel.Columns.LAST_UPDATED + TEXT ); } private static String[] nameableColumns() { return Utils.appendInNewArray(identifiableColumns(), - BaseNameableObjectModel.Columns.SHORT_NAME + " TEXT", - BaseNameableObjectModel.Columns.DISPLAY_SHORT_NAME + " TEXT", - BaseNameableObjectModel.Columns.DESCRIPTION + " TEXT", - BaseNameableObjectModel.Columns.DISPLAY_DESCRIPTION + " TEXT" + BaseNameableObjectModel.Columns.SHORT_NAME + TEXT, + BaseNameableObjectModel.Columns.DISPLAY_SHORT_NAME + TEXT, + BaseNameableObjectModel.Columns.DESCRIPTION + TEXT, + BaseNameableObjectModel.Columns.DISPLAY_DESCRIPTION + TEXT ); } diff --git a/core/src/main/java/org/hisp/dhis/android/core/common/SQLStatementWrapper.java b/core/src/main/java/org/hisp/dhis/android/core/common/SQLStatementWrapper.java index 86dd51e76d..c08cc9de25 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/common/SQLStatementWrapper.java +++ b/core/src/main/java/org/hisp/dhis/android/core/common/SQLStatementWrapper.java @@ -36,10 +36,12 @@ public class SQLStatementWrapper { public final SQLiteStatement insert; public final SQLiteStatement update; final SQLiteStatement deleteById; + final String selectUids; SQLStatementWrapper(SQLStatementBuilder builder, DatabaseAdapter databaseAdapter) { this.insert = databaseAdapter.compileStatement(builder.insert()); this.update = databaseAdapter.compileStatement(builder.update()); this.deleteById = databaseAdapter.compileStatement(builder.deleteById()); + this.selectUids = builder.selectUids(); } } \ No newline at end of file diff --git a/core/src/main/java/org/hisp/dhis/android/core/common/StoreFactory.java b/core/src/main/java/org/hisp/dhis/android/core/common/StoreFactory.java index 358a9063b8..1ee37f34ee 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/common/StoreFactory.java +++ b/core/src/main/java/org/hisp/dhis/android/core/common/StoreFactory.java @@ -30,12 +30,11 @@ import org.hisp.dhis.android.core.data.database.DatabaseAdapter; -@SuppressWarnings("PMD") -public class StoreFactory { +public final class StoreFactory { private StoreFactory() {} - @SuppressWarnings("PMD") + @SuppressWarnings("PMD.UseVarargs") public static IdentifiableObjectStore identifiableStore(DatabaseAdapter databaseAdapter, String tableName, String[] columns) { SQLStatementBuilder statementBuilder = new SQLStatementBuilder(tableName, columns, new String[]{}); @@ -43,7 +42,7 @@ private StoreFactory() {} return new IdentifiableObjectStoreImpl<>(databaseAdapter, statements, statementBuilder); } - @SuppressWarnings("PMD") + @SuppressWarnings("PMD.UseVarargs") static ObjectStore objectStore(DatabaseAdapter databaseAdapter, String tableName, String[] columns) { SQLStatementBuilder statementBuilder = new SQLStatementBuilder(tableName, columns, new String[]{}); @@ -51,7 +50,7 @@ private StoreFactory() {} statementBuilder.insert()), statementBuilder); } - @SuppressWarnings("PMD") + @SuppressWarnings("PMD.UseVarargs") public static ObjectWithoutUidStore objectWithoutUidStore(DatabaseAdapter databaseAdapter, String tableName, String[] columns, String[] whereUpdateColumns) { diff --git a/core/src/main/java/org/hisp/dhis/android/core/common/UidsQuery.java b/core/src/main/java/org/hisp/dhis/android/core/common/UidsQuery.java new file mode 100644 index 0000000000..876129015c --- /dev/null +++ b/core/src/main/java/org/hisp/dhis/android/core/common/UidsQuery.java @@ -0,0 +1,26 @@ +package org.hisp.dhis.android.core.common; + +import com.google.auto.value.AutoValue; + +import java.util.Set; + +import javax.annotation.Nullable; + +@AutoValue +public abstract class UidsQuery extends BaseQuery { + + @Nullable + public abstract Set uids(); + + @Nullable + abstract Integer limit(); + + @Override + boolean isValid() { + return limit() == null || uids().size() <= limit(); + } + + public static UidsQuery create(Set uids, Integer limit) { + return new AutoValue_UidsQuery(1, BaseQuery.DEFAULT_PAGE_SIZE, false, uids, limit); + } +} diff --git a/core/src/main/java/org/hisp/dhis/android/core/common/ValueType.java b/core/src/main/java/org/hisp/dhis/android/core/common/ValueType.java index 623a5d6be3..527e320c82 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/common/ValueType.java +++ b/core/src/main/java/org/hisp/dhis/android/core/common/ValueType.java @@ -66,7 +66,9 @@ public enum ValueType { //New values: AGE(Date.class), - URL(String.class); + URL(String.class), + + IMAGE(String.class); private static final Set INTEGER_TYPES = new HashSet<>(Arrays.asList(INTEGER, INTEGER_POSITIVE, INTEGER_NEGATIVE, INTEGER_ZERO_OR_POSITIVE)); @@ -78,7 +80,7 @@ public enum ValueType { TRUE_ONLY)); private static final Set TEXT_TYPES = new HashSet<>(Arrays.asList(TEXT, LONG_TEXT, - LETTER, COORDINATE, TIME)); + LETTER, COORDINATE, TIME, IMAGE)); private static final Set DATE_TYPES = new HashSet<>(Arrays.asList(DATE, DATETIME)); diff --git a/core/src/main/java/org/hisp/dhis/android/core/common/ValueTypeDeviceRendering.java b/core/src/main/java/org/hisp/dhis/android/core/common/ValueTypeDeviceRendering.java new file mode 100644 index 0000000000..c6c09d6099 --- /dev/null +++ b/core/src/main/java/org/hisp/dhis/android/core/common/ValueTypeDeviceRendering.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2017, University of Oslo + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.hisp.dhis.android.core.common; + +import android.support.annotation.Nullable; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.auto.value.AutoValue; + +@AutoValue +public abstract class ValueTypeDeviceRendering { + private static final String TYPE = "type"; + private static final String MIN = "min"; + private static final String MAX = "max"; + private static final String STEP = "step"; + private static final String DECIMAL_POINTS = "decimalPoints"; + + @Nullable + @JsonProperty(TYPE) + public abstract ValueTypeRenderingType type(); + + @Nullable + @JsonProperty(MIN) + public abstract Integer min(); + + @Nullable + @JsonProperty(MAX) + public abstract Integer max(); + + @Nullable + @JsonProperty(STEP) + public abstract Integer step(); + + @Nullable + @JsonProperty(DECIMAL_POINTS) + public abstract Integer decimalPoints(); + + @JsonCreator + public static ValueTypeDeviceRendering create( + @JsonProperty(TYPE) ValueTypeRenderingType type, + @JsonProperty(MIN) Integer min, + @JsonProperty(MAX) Integer max, + @JsonProperty(STEP) Integer step, + @JsonProperty(DECIMAL_POINTS) Integer decimalPoints) { + + return new AutoValue_ValueTypeDeviceRendering(type, min, max, step, decimalPoints); + } +} \ No newline at end of file diff --git a/core/src/main/java/org/hisp/dhis/android/core/common/ValueTypeDeviceRenderingHandler.java b/core/src/main/java/org/hisp/dhis/android/core/common/ValueTypeDeviceRenderingHandler.java new file mode 100644 index 0000000000..5e70673bc8 --- /dev/null +++ b/core/src/main/java/org/hisp/dhis/android/core/common/ValueTypeDeviceRenderingHandler.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2017, University of Oslo + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.hisp.dhis.android.core.common; + +import org.hisp.dhis.android.core.data.database.DatabaseAdapter; + +public class ValueTypeDeviceRenderingHandler implements DictionaryTableHandler { + + private final ObjectWithoutUidStore store; + private final String deviceType; + + ValueTypeDeviceRenderingHandler(ObjectWithoutUidStore store, + String deviceType) { + this.store = store; + this.deviceType = deviceType; + } + + @Override + public void handle(ValueTypeDeviceRendering deviceRendering, String uid, String objectTable) { + if (deviceRendering != null) { + ValueTypeDeviceRenderingModel model = ValueTypeDeviceRenderingModel.fromPojo( + deviceRendering, uid, objectTable, deviceType); + store.updateOrInsertWhere(model); + } + } + + public static ValueTypeDeviceRenderingHandler create(DatabaseAdapter databaseAdapter, + String deviceType) { + return new ValueTypeDeviceRenderingHandler( + ValueTypeDeviceRenderingStore.create(databaseAdapter), + deviceType); + } +} diff --git a/core/src/main/java/org/hisp/dhis/android/core/common/ValueTypeDeviceRenderingModel.java b/core/src/main/java/org/hisp/dhis/android/core/common/ValueTypeDeviceRenderingModel.java new file mode 100644 index 0000000000..b53b47c06b --- /dev/null +++ b/core/src/main/java/org/hisp/dhis/android/core/common/ValueTypeDeviceRenderingModel.java @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2017, University of Oslo + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.hisp.dhis.android.core.common; + +import android.content.ContentValues; +import android.database.Cursor; +import android.database.sqlite.SQLiteStatement; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import com.gabrielittner.auto.value.cursor.ColumnAdapter; +import com.gabrielittner.auto.value.cursor.ColumnName; +import com.google.auto.value.AutoValue; + +import org.hisp.dhis.android.core.utils.Utils; + +import static org.hisp.dhis.android.core.utils.StoreUtils.sqLiteBind; + +@AutoValue +public abstract class ValueTypeDeviceRenderingModel extends BaseModel implements UpdateWhereStatementBinder { + public static final String TABLE = "ValueTypeDeviceRendering"; + + public abstract static class Columns extends BaseModel.Columns { + public static final String UID = BaseIdentifiableObjectModel.Columns.UID; + public static final String OBJECT_TABLE = "objectTable"; + public static final String DEVICE_TYPE = "deviceType"; + public static final String TYPE = "type"; + public static final String MIN = "min"; + public static final String MAX = "max"; + public static final String STEP = "step"; + public static final String DECIMAL_POINTS = "decimalPoints"; + + public static String[] all() { + return Utils.appendInNewArray(BaseModel.Columns.all(), + UID, OBJECT_TABLE, DEVICE_TYPE, TYPE, MIN, MAX, STEP, DECIMAL_POINTS); + } + + static String[] whereUpdate() { + return new String[]{UID, DEVICE_TYPE}; + } + } + + public static ValueTypeDeviceRenderingModel create(Cursor cursor) { + return AutoValue_ValueTypeDeviceRenderingModel.createFromCursor(cursor); + } + + public static final LinkModelFactory factory + = new LinkModelFactory() { + @Override + public ValueTypeDeviceRenderingModel fromCursor(Cursor cursor) { + return create(cursor); + } + }; + + public static ValueTypeDeviceRenderingModel fromPojo(ValueTypeDeviceRendering deviceRendering, + String uid, String objectTable, + String deviceType) { + return ValueTypeDeviceRenderingModel.builder() + .uid(uid) + .objectTable(objectTable) + .deviceType(deviceType) + .type(deviceRendering.type()) + .min(deviceRendering.min()) + .max(deviceRendering.max()) + .step(deviceRendering.step()) + .decimalPoints(deviceRendering.decimalPoints()) + .build(); + } + + public static Builder builder() { + return new $$AutoValue_ValueTypeDeviceRenderingModel.Builder(); + } + + @Nullable + @ColumnName(Columns.UID) + public abstract String uid(); + + @Nullable + @ColumnName(Columns.OBJECT_TABLE) + public abstract String objectTable(); + + @Nullable + @ColumnName(Columns.DEVICE_TYPE) + public abstract String deviceType(); + + @Nullable + @ColumnName(Columns.TYPE) + @ColumnAdapter(ValueTypeRenderingTypeColumnAdapter.class) + public abstract ValueTypeRenderingType type(); + + @Nullable + @ColumnName(Columns.MIN) + public abstract Integer min(); + + @Nullable + @ColumnName(Columns.MAX) + public abstract Integer max(); + + @Nullable + @ColumnName(Columns.STEP) + public abstract Integer step(); + + @Nullable + @ColumnName(Columns.DECIMAL_POINTS) + public abstract Integer decimalPoints(); + + @NonNull + public abstract ContentValues toContentValues(); + + @Override + public void bindToStatement(@NonNull SQLiteStatement sqLiteStatement) { + sqLiteBind(sqLiteStatement, 1, uid()); + sqLiteBind(sqLiteStatement, 2, objectTable()); + sqLiteBind(sqLiteStatement, 3, deviceType()); + sqLiteBind(sqLiteStatement, 4, type()); + sqLiteBind(sqLiteStatement, 5, min()); + sqLiteBind(sqLiteStatement, 6, max()); + sqLiteBind(sqLiteStatement, 7, step()); + sqLiteBind(sqLiteStatement, 8, decimalPoints()); + } + + @Override + public void bindToUpdateWhereStatement(@NonNull SQLiteStatement sqLiteStatement) { + sqLiteBind(sqLiteStatement, 9, uid()); + sqLiteBind(sqLiteStatement, 10, deviceType()); + } + + @AutoValue.Builder + public static abstract class Builder extends BaseModel.Builder { + public abstract Builder uid(String uid); + + public abstract Builder objectTable(String objectTable); + + public abstract Builder deviceType(String deviceType); + + public abstract Builder min(Integer min); + + public abstract Builder type(ValueTypeRenderingType type); + + public abstract Builder max(Integer max); + + public abstract Builder step(Integer step); + + public abstract Builder decimalPoints(Integer decimalPoints); + + public abstract ValueTypeDeviceRenderingModel build(); + } +} diff --git a/core/src/main/java/org/hisp/dhis/android/core/common/ValueTypeDeviceRenderingStore.java b/core/src/main/java/org/hisp/dhis/android/core/common/ValueTypeDeviceRenderingStore.java new file mode 100644 index 0000000000..5ad8fbfa8e --- /dev/null +++ b/core/src/main/java/org/hisp/dhis/android/core/common/ValueTypeDeviceRenderingStore.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2017, University of Oslo + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.hisp.dhis.android.core.common; + +import org.hisp.dhis.android.core.data.database.DatabaseAdapter; + +public final class ValueTypeDeviceRenderingStore { + + private ValueTypeDeviceRenderingStore() {} + + public static ObjectWithoutUidStore create(DatabaseAdapter databaseAdapter) { + return StoreFactory.objectWithoutUidStore(databaseAdapter, ValueTypeDeviceRenderingModel.TABLE, + ValueTypeDeviceRenderingModel.Columns.all(), ValueTypeDeviceRenderingModel.Columns.whereUpdate()); + } +} \ No newline at end of file diff --git a/core/src/main/java/org/hisp/dhis/android/core/common/ValueTypeRendering.java b/core/src/main/java/org/hisp/dhis/android/core/common/ValueTypeRendering.java new file mode 100644 index 0000000000..9a0f4bd147 --- /dev/null +++ b/core/src/main/java/org/hisp/dhis/android/core/common/ValueTypeRendering.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2017, University of Oslo + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.hisp.dhis.android.core.common; + +import android.support.annotation.Nullable; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.auto.value.AutoValue; + +@AutoValue +public abstract class ValueTypeRendering { + public static final String DESKTOP = "DESKTOP"; + public static final String MOBILE = "MOBILE"; + + @Nullable + @JsonProperty(DESKTOP) + public abstract ValueTypeDeviceRendering desktop(); + + @Nullable + @JsonProperty(MOBILE) + public abstract ValueTypeDeviceRendering mobile(); + + @JsonCreator + public static ValueTypeRendering create( + @JsonProperty(DESKTOP) ValueTypeDeviceRendering desktop, + @JsonProperty(MOBILE) ValueTypeDeviceRendering mobile) { + + return new AutoValue_ValueTypeRendering(desktop, mobile); + } +} \ No newline at end of file diff --git a/core/src/main/java/org/hisp/dhis/android/core/common/ValueTypeRenderingHandler.java b/core/src/main/java/org/hisp/dhis/android/core/common/ValueTypeRenderingHandler.java new file mode 100644 index 0000000000..9eb7a4ab04 --- /dev/null +++ b/core/src/main/java/org/hisp/dhis/android/core/common/ValueTypeRenderingHandler.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2017, University of Oslo + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.hisp.dhis.android.core.common; + +import org.hisp.dhis.android.core.data.database.DatabaseAdapter; + +public class ValueTypeRenderingHandler implements DictionaryTableHandler { + + private final DictionaryTableHandler desktopHandler; + private final DictionaryTableHandler mobileHandler; + + ValueTypeRenderingHandler(DictionaryTableHandler desktopHandler, + DictionaryTableHandler mobileHandler) { + this.desktopHandler = desktopHandler; + this.mobileHandler = mobileHandler; + } + + @Override + public void handle(ValueTypeRendering renderType, String uid, String objectTable) { + if (renderType != null) { + desktopHandler.handle(renderType.desktop(), uid, objectTable); + mobileHandler.handle(renderType.mobile(), uid, objectTable); + } + } + + public static ValueTypeRenderingHandler create(DatabaseAdapter databaseAdapter) { + return new ValueTypeRenderingHandler( + ValueTypeDeviceRenderingHandler.create(databaseAdapter, ValueTypeRendering.DESKTOP), + ValueTypeDeviceRenderingHandler.create(databaseAdapter, ValueTypeRendering.MOBILE)); + } +} diff --git a/core/src/main/java/org/hisp/dhis/android/core/common/ValueTypeRenderingType.java b/core/src/main/java/org/hisp/dhis/android/core/common/ValueTypeRenderingType.java new file mode 100644 index 0000000000..fd35ecb76a --- /dev/null +++ b/core/src/main/java/org/hisp/dhis/android/core/common/ValueTypeRenderingType.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2017, University of Oslo + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.hisp.dhis.android.core.common; + +public enum ValueTypeRenderingType { + DEFAULT, + DROPDOWN, + VERTICAL_RADIOBUTTONS, + HORIZONTAL_RADIOBUTTONS, + VERTICAL_CHECKBOXES, + HORIZONTAL_CHECKBOXES, + SHARED_HEADER_RADIOBUTTONS, + ICONS_AS_BUTTONS, + SPINNER, + ICON, + TOGGLE, + VALUE, + SLIDER, + LINEAR_SCALE +} \ No newline at end of file diff --git a/core/src/main/java/org/hisp/dhis/android/core/common/ValueTypeRenderingTypeColumnAdapter.java b/core/src/main/java/org/hisp/dhis/android/core/common/ValueTypeRenderingTypeColumnAdapter.java new file mode 100644 index 0000000000..e1378b1363 --- /dev/null +++ b/core/src/main/java/org/hisp/dhis/android/core/common/ValueTypeRenderingTypeColumnAdapter.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2017, University of Oslo + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.hisp.dhis.android.core.common; + +import org.hisp.dhis.android.core.data.database.EnumColumnAdapter; + +public class ValueTypeRenderingTypeColumnAdapter extends EnumColumnAdapter { + @Override + protected Class getEnumClass() { + return ValueTypeRenderingType.class; + } +} \ No newline at end of file diff --git a/core/src/main/java/org/hisp/dhis/android/core/data/database/DbOpenHelper.java b/core/src/main/java/org/hisp/dhis/android/core/data/database/DbOpenHelper.java index 86e16c9f74..47e8b25b9c 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/data/database/DbOpenHelper.java +++ b/core/src/main/java/org/hisp/dhis/android/core/data/database/DbOpenHelper.java @@ -42,19 +42,26 @@ import org.hisp.dhis.android.core.category.CategoryOptionComboCategoryLinkModel; import org.hisp.dhis.android.core.category.CategoryOptionComboModel; import org.hisp.dhis.android.core.category.CategoryOptionModel; +import org.hisp.dhis.android.core.common.ObjectStyleModel; import org.hisp.dhis.android.core.common.SQLStatementBuilder; +import org.hisp.dhis.android.core.common.ValueTypeDeviceRenderingModel; import org.hisp.dhis.android.core.configuration.ConfigurationModel; import org.hisp.dhis.android.core.constant.ConstantModel; import org.hisp.dhis.android.core.dataelement.DataElementModel; import org.hisp.dhis.android.core.dataset.DataSetDataElementLinkModel; import org.hisp.dhis.android.core.dataset.DataSetModel; import org.hisp.dhis.android.core.dataset.DataSetOrganisationUnitLinkModel; +import org.hisp.dhis.android.core.datavalue.DataValueModel; import org.hisp.dhis.android.core.enrollment.EnrollmentModel; import org.hisp.dhis.android.core.event.EventModel; +import org.hisp.dhis.android.core.indicator.DataSetIndicatorLinkModel; +import org.hisp.dhis.android.core.indicator.IndicatorModel; +import org.hisp.dhis.android.core.indicator.IndicatorTypeModel; import org.hisp.dhis.android.core.option.OptionModel; import org.hisp.dhis.android.core.option.OptionSetModel; import org.hisp.dhis.android.core.organisationunit.OrganisationUnitModel; import org.hisp.dhis.android.core.organisationunit.OrganisationUnitProgramLinkModel; +import org.hisp.dhis.android.core.period.PeriodModel; import org.hisp.dhis.android.core.program.ProgramIndicatorModel; import org.hisp.dhis.android.core.program.ProgramModel; import org.hisp.dhis.android.core.program.ProgramRuleActionModel; @@ -79,7 +86,6 @@ import org.hisp.dhis.android.core.user.UserModel; import org.hisp.dhis.android.core.user.UserOrganisationUnitLinkModel; import org.hisp.dhis.android.core.user.UserRoleModel; -import org.hisp.dhis.android.core.user.UserRoleProgramLinkModel; import java.io.BufferedReader; import java.io.IOException; @@ -95,7 +101,7 @@ public class DbOpenHelper extends CustomSQLBriteOpenHelper { @VisibleForTesting - static int VERSION = 4; + static int VERSION = 9; public String mockedSqlDatabase = ""; private static final String CREATE_CONFIGURATION_TABLE = "CREATE TABLE " + ConfigurationModel.CONFIGURATION + " (" + @@ -343,6 +349,7 @@ public class DbOpenHelper extends CustomSQLBriteOpenHelper { ProgramModel.Columns.RELATED_PROGRAM + " TEXT," + ProgramModel.Columns.TRACKED_ENTITY + " TEXT," + ProgramModel.Columns.CATEGORY_COMBO + " TEXT," + + ProgramModel.Columns.ACCESS_DATA_WRITE + " INTEGER," + " FOREIGN KEY (" + ProgramModel.Columns.RELATIONSHIP_TYPE + ")" + " REFERENCES " + RelationshipTypeModel.TABLE + " (" + RelationshipTypeModel.Columns.UID + ")" + @@ -384,7 +391,7 @@ public class DbOpenHelper extends CustomSQLBriteOpenHelper { DataElementModel.Columns.DIMENSION + " TEXT," + DataElementModel.Columns.DISPLAY_FORM_NAME + " TEXT," + DataElementModel.Columns.OPTION_SET + " TEXT," + - DataElementModel.Columns.CATEGORY_COMBO + " TEXT," +" FOREIGN KEY ( " + DataElementModel.Columns.CATEGORY_COMBO + " TEXT," + " FOREIGN KEY ( " + DataElementModel.Columns.OPTION_SET + ")" + " REFERENCES " + OptionSetModel.TABLE + " (" + OptionSetModel.Columns.UID + ")" + " ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED" @@ -463,6 +470,8 @@ public class DbOpenHelper extends CustomSQLBriteOpenHelper { ProgramStageSectionModel.Columns.LAST_UPDATED + " TEXT," + ProgramStageSectionModel.Columns.SORT_ORDER + " INTEGER," + ProgramStageSectionModel.Columns.PROGRAM_STAGE + " TEXT NOT NULL," + + ProgramStageSectionModel.Columns.DESKTOP_RENDER_TYPE + " TEXT," + + ProgramStageSectionModel.Columns.MOBILE_RENDER_TYPE + " TEXT," + " FOREIGN KEY ( " + ProgramStageSectionModel.Columns.PROGRAM_STAGE + ")" + " REFERENCES " + ProgramStageModel.TABLE + " (" + ProgramStageModel.Columns.UID + ")" + " ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED" + @@ -876,21 +885,6 @@ public class DbOpenHelper extends CustomSQLBriteOpenHelper { UserRoleModel.Columns.LAST_UPDATED + " TEXT" + ");"; - private static final String CREATE_USER_ROLE_PROGRAM_TABLE = "CREATE TABLE " + - UserRoleProgramLinkModel.TABLE + " (" + - UserRoleProgramLinkModel.Columns.ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + - UserRoleProgramLinkModel.Columns.USER_ROLE + " TEXT NOT NULL," + - UserRoleProgramLinkModel.Columns.PROGRAM + " TEXT NOT NULL," + - " FOREIGN KEY (" + UserRoleProgramLinkModel.Columns.USER_ROLE + ") " + - " REFERENCES " + UserRoleModel.TABLE + " (" + UserRoleModel.Columns.UID + ")" + - " ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED," + - " FOREIGN KEY (" + UserRoleProgramLinkModel.Columns.PROGRAM + ") " + - " REFERENCES " + ProgramModel.TABLE + " (" + ProgramModel.Columns.UID + ")" + - " ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED," + - " UNIQUE (" + UserRoleProgramLinkModel.Columns.USER_ROLE + ", " + - UserRoleProgramLinkModel.Columns.PROGRAM + ")" + - ");"; - private static final String CREATE_PROGRAM_STAGE_SECTION_PROGRAM_INDICATOR_LINK_TABLE = "CREATE TABLE " + ProgramStageSectionProgramIndicatorLinkModel.TABLE + " (" + @@ -935,6 +929,7 @@ public class DbOpenHelper extends CustomSQLBriteOpenHelper { DataSetModel.Columns.DATA_ELEMENT_DECORATION + " INTEGER," + DataSetModel.Columns.RENDER_AS_TABS + " INTEGER," + DataSetModel.Columns.RENDER_HORIZONTALLY + " INTEGER," + + DataSetModel.Columns.ACCESS_DATA_WRITE + " INTEGER," + " FOREIGN KEY ( " + DataSetModel.Columns.CATEGORY_COMBO + ")" + " REFERENCES " + CategoryComboModel.TABLE + " (" + CategoryComboModel.Columns.UID + ")" + " ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED" @@ -969,6 +964,111 @@ public class DbOpenHelper extends CustomSQLBriteOpenHelper { DataSetOrganisationUnitLinkModel.Columns.ORGANISATION_UNIT + ")" ); + private static final String CREATE_INDICATOR_TABLE = + SQLStatementBuilder.createNameableModelTable(IndicatorModel.TABLE, + IndicatorModel.Columns.ANNUALIZED + " INTEGER," + + IndicatorModel.Columns.INDICATOR_TYPE + " TEXT," + + IndicatorModel.Columns.NUMERATOR + " TEXT," + + IndicatorModel.Columns.NUMERATOR_DESCRIPTION + " TEXT," + + IndicatorModel.Columns.DENOMINATOR + " TEXT," + + IndicatorModel.Columns.DENOMINATOR_DESCRIPTION + " TEXT," + + IndicatorModel.Columns.URL + " TEXT," + + " FOREIGN KEY ( " + IndicatorModel.Columns.INDICATOR_TYPE + ")" + + " REFERENCES " + IndicatorTypeModel.TABLE + " (" + IndicatorTypeModel.Columns.UID + ")" + + " ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED" + ); + + private static final String CREATE_INDICATOR_TYPE_TABLE = + SQLStatementBuilder.createNameableModelTable(IndicatorTypeModel.TABLE, + IndicatorTypeModel.Columns.NUMBER + " INTEGER," + + IndicatorTypeModel.Columns.FACTOR + " INTEGER" + ); + + private static final String CREATE_DATA_SET_INDICATOR_LINK_TABLE = + SQLStatementBuilder.createModelTable(DataSetIndicatorLinkModel.TABLE, + DataSetIndicatorLinkModel.Columns.DATA_SET + " TEXT NOT NULL," + + DataSetIndicatorLinkModel.Columns.INDICATOR + " TEXT NOT NULL," + + " FOREIGN KEY (" + DataSetIndicatorLinkModel.Columns.DATA_SET + ") " + + " REFERENCES " + DataSetModel.TABLE + " (" + DataSetModel.Columns.UID + ")" + + " ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED," + + " FOREIGN KEY (" + DataSetIndicatorLinkModel.Columns.INDICATOR + ") " + + " REFERENCES " + IndicatorModel.TABLE + " (" + IndicatorModel.Columns.UID + ")" + + " ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED," + + " UNIQUE (" + DataSetIndicatorLinkModel.Columns.DATA_SET + ", " + + DataSetIndicatorLinkModel.Columns.INDICATOR + ")" + ); + + private static final String CREATE_DATA_VALUE_TABLE = + SQLStatementBuilder.createModelTable(DataValueModel.TABLE, + DataValueModel.Columns.DATA_ELEMENT + " TEXT NOT NULL," + + DataValueModel.Columns.PERIOD + " TEXT NOT NULL," + + DataValueModel.Columns.ORGANISATION_UNIT + " TEXT NOT NULL," + + DataValueModel.Columns.CATEGORY_OPTION_COMBO + " TEXT NOT NULL," + + DataValueModel.Columns.ATTRIBUTE_OPTION_COMBO + " TEXT NOT NULL," + + DataValueModel.Columns.VALUE + " TEXT," + + DataValueModel.Columns.STORED_BY + " TEXT," + + DataValueModel.Columns.CREATED + " TEXT," + + DataValueModel.Columns.LAST_UPDATED + " TEXT," + + DataValueModel.Columns.COMMENT + " TEXT," + + DataValueModel.Columns.FOLLOW_UP + " INTEGER," + + " FOREIGN KEY (" + DataValueModel.Columns.DATA_ELEMENT + ") " + + " REFERENCES " + DataElementModel.TABLE + " (" + DataElementModel.Columns.UID + ")" + + " ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED," + + " FOREIGN KEY (" + DataValueModel.Columns.PERIOD + ") " + + " REFERENCES " + PeriodModel.TABLE + " (" + + PeriodModel.Columns.PERIOD_ID + ")" + + " FOREIGN KEY (" + DataValueModel.Columns.ORGANISATION_UNIT + ") " + + " REFERENCES " + OrganisationUnitModel.TABLE + " (" + + OrganisationUnitModel.Columns.UID + ")" + + " ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED," + + " FOREIGN KEY (" + DataValueModel.Columns.CATEGORY_OPTION_COMBO + ") " + + " REFERENCES " + CategoryOptionComboModel.TABLE + " (" + + CategoryOptionComboModel.Columns.UID + ")" + + " ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED," + + " FOREIGN KEY (" + DataValueModel.Columns.ATTRIBUTE_OPTION_COMBO + ") " + + " REFERENCES " + CategoryOptionComboModel.TABLE + " (" + + CategoryOptionComboModel.Columns.UID + ")" + + " ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED," + + " UNIQUE (" + + DataValueModel.Columns.DATA_ELEMENT + ", " + + DataValueModel.Columns.PERIOD + ", " + + DataValueModel.Columns.ORGANISATION_UNIT + ", " + + DataValueModel.Columns.CATEGORY_OPTION_COMBO + ", " + + DataValueModel.Columns.ATTRIBUTE_OPTION_COMBO + ")" + ); + + private static final String CREATE_PERIOD_TABLE = + SQLStatementBuilder.createModelTable(PeriodModel.TABLE, + PeriodModel.Columns.PERIOD_ID + " TEXT," + + PeriodModel.Columns.PERIOD_TYPE + " TEXT," + + PeriodModel.Columns.START_DATE + " TEXT," + + PeriodModel.Columns.END_DATE + " TEXT," + + " UNIQUE (" + PeriodModel.Columns.PERIOD_ID + ")" + ); + + private static final String CREATE_OBJECT_STYLE_TABLE = + SQLStatementBuilder.createModelTable(ObjectStyleModel.TABLE, + ObjectStyleModel.Columns.UID + " TEXT," + + ObjectStyleModel.Columns.OBJECT_TABLE + " TEXT," + + ObjectStyleModel.Columns.COLOR + " TEXT," + + ObjectStyleModel.Columns.ICON + " TEXT," + + " UNIQUE (" + ObjectStyleModel.Columns.UID + ")" + ); + + private static final String CREATE_VALUE_TYPE_DEVICE_RENDERING_TABLE = + SQLStatementBuilder.createModelTable(ValueTypeDeviceRenderingModel.TABLE, + ValueTypeDeviceRenderingModel.Columns.UID + " TEXT," + + ValueTypeDeviceRenderingModel.Columns.OBJECT_TABLE + " TEXT," + + ValueTypeDeviceRenderingModel.Columns.DEVICE_TYPE + " TEXT," + + ValueTypeDeviceRenderingModel.Columns.TYPE + " TEXT," + + ValueTypeDeviceRenderingModel.Columns.MIN + " INTEGER," + + ValueTypeDeviceRenderingModel.Columns.MAX + " INTEGER," + + ValueTypeDeviceRenderingModel.Columns.STEP + " INTEGER," + + ValueTypeDeviceRenderingModel.Columns.DECIMAL_POINTS + " INTEGER," + + " UNIQUE (" + ValueTypeDeviceRenderingModel.Columns.UID + ", " + + ValueTypeDeviceRenderingModel.Columns.DEVICE_TYPE + ")" + ); + /** * This method should be used only for testing purposes */ @@ -1012,7 +1112,6 @@ private static SQLiteDatabase create(SQLiteDatabase database) { database.execSQL(CREATE_RESOURCE_TABLE); database.execSQL(CREATE_ORGANISATION_UNIT_PROGRAM_LINK_TABLE); database.execSQL(CREATE_USER_ROLE_TABLE); - database.execSQL(CREATE_USER_ROLE_PROGRAM_TABLE); database.execSQL(CREATE_PROGRAM_STAGE_SECTION_PROGRAM_INDICATOR_LINK_TABLE); database.execSQL(CREATE_CATEGORY_TABLE); database.execSQL(CREATE_CATEGORY_OPTION_TABLE); @@ -1024,6 +1123,13 @@ private static SQLiteDatabase create(SQLiteDatabase database) { database.execSQL(CREATE_DATA_SET_TABLE); database.execSQL(CREATE_DATA_SET_DATA_ELEMENT_LINK_TABLE); database.execSQL(CREATE_DATA_SET_ORGANISATION_UNIT_LINK_TABLE); + database.execSQL(CREATE_INDICATOR_TABLE); + database.execSQL(CREATE_INDICATOR_TYPE_TABLE); + database.execSQL(CREATE_DATA_SET_INDICATOR_LINK_TABLE); + database.execSQL(CREATE_DATA_VALUE_TABLE); + database.execSQL(CREATE_PERIOD_TABLE); + database.execSQL(CREATE_OBJECT_STYLE_TABLE); + database.execSQL(CREATE_VALUE_TYPE_DEVICE_RENDERING_TABLE); return database; } diff --git a/core/src/main/java/org/hisp/dhis/android/core/data/database/DbPeriodTypeColumnAdapter.java b/core/src/main/java/org/hisp/dhis/android/core/data/database/DbPeriodTypeColumnAdapter.java index 7cffe43900..a81b475346 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/data/database/DbPeriodTypeColumnAdapter.java +++ b/core/src/main/java/org/hisp/dhis/android/core/data/database/DbPeriodTypeColumnAdapter.java @@ -28,7 +28,7 @@ package org.hisp.dhis.android.core.data.database; -import org.hisp.dhis.android.core.common.PeriodType; +import org.hisp.dhis.android.core.period.PeriodType; public class DbPeriodTypeColumnAdapter extends EnumColumnAdapter { @Override diff --git a/core/src/main/java/org/hisp/dhis/android/core/dataelement/DataElement.java b/core/src/main/java/org/hisp/dhis/android/core/dataelement/DataElement.java index 344bbbf3a2..830d962fd7 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/dataelement/DataElement.java +++ b/core/src/main/java/org/hisp/dhis/android/core/dataelement/DataElement.java @@ -36,8 +36,10 @@ import org.hisp.dhis.android.core.category.CategoryComboModel; import org.hisp.dhis.android.core.common.BaseNameableObject; +import org.hisp.dhis.android.core.common.ObjectStyle; import org.hisp.dhis.android.core.common.ObjectWithUid; import org.hisp.dhis.android.core.common.ValueType; +import org.hisp.dhis.android.core.common.ValueTypeRendering; import org.hisp.dhis.android.core.data.api.Field; import org.hisp.dhis.android.core.data.api.Fields; import org.hisp.dhis.android.core.data.api.NestedField; @@ -57,6 +59,8 @@ public abstract class DataElement extends BaseNameableObject { private final static String DISPLAY_FORM_NAME = "displayFormName"; private final static String OPTION_SET = "optionSet"; private final static String CATEGORY_COMBO = "categoryCombo"; + private final static String STYLE = "style"; + private final static String RENDER_TYPE = "renderType"; public static final Field uid = Field.create(UID); private static final Field code = Field.create(CODE); @@ -81,13 +85,18 @@ public abstract class DataElement extends BaseNameableObject { private static final NestedField optionSet = NestedField.create(OPTION_SET); private static final NestedField categoryCombo = NestedField.create(CATEGORY_COMBO); + private static final NestedField style = + NestedField.create(STYLE); + private static final NestedField renderType = + NestedField.create(RENDER_TYPE); public static final Fields allFields = Fields.builder().fields( uid, code, name, displayName, created, lastUpdated, shortName, displayShortName, description, displayDescription, deleted, valueType, zeroIsSignificant, aggregationType, formName, numberType, domainType, dimension, displayFormName, optionSet.with(OptionSet.uid, OptionSet.version), - categoryCombo.with(ObjectWithUid.uid)).build(); + categoryCombo.with(ObjectWithUid.uid), style.with(ObjectStyle.allFields), + renderType).build(); @Nullable @JsonProperty(VALUE_TYPE) @@ -125,15 +134,27 @@ public abstract class DataElement extends BaseNameableObject { @JsonProperty(OPTION_SET) public abstract OptionSet optionSet(); + String optionSetUid() { + OptionSet optionSet = optionSet(); + return optionSet == null ? null : optionSet.uid(); + } + @Nullable @JsonProperty(CATEGORY_COMBO) public abstract ObjectWithUid categoryCombo(); - @SuppressWarnings("PMD") - public String categoryComboUid() { - return categoryCombo() != null ? categoryCombo().uid() : - CategoryComboModel.DEFAULT_UID; + String categoryComboUid() { + ObjectWithUid combo = categoryCombo(); + return combo == null ? CategoryComboModel.DEFAULT_UID : combo.uid(); } + + @Nullable + @JsonProperty(STYLE) + public abstract ObjectStyle style(); + + @Nullable + @JsonProperty(RENDER_TYPE) + public abstract ValueTypeRendering renderType(); @JsonCreator public static DataElement create( @@ -157,13 +178,16 @@ public static DataElement create( @JsonProperty(DISPLAY_FORM_NAME) String displayFormName, @JsonProperty(OPTION_SET) OptionSet optionSet, @JsonProperty(CATEGORY_COMBO) ObjectWithUid categoryCombo, + @JsonProperty(STYLE) ObjectStyle style, + @JsonProperty(RENDER_TYPE) ValueTypeRendering renderType, @JsonProperty(DELETED) Boolean deleted) { return new AutoValue_DataElement(uid, code, name, displayName, created, lastUpdated, deleted, shortName, displayShortName, description, displayDescription, valueType, zeroIsSignificant, aggregationType, formName, numberType, - domainType, dimension, displayFormName, optionSet, categoryCombo); + domainType, dimension, displayFormName, optionSet, categoryCombo, style, + renderType); } } diff --git a/core/src/main/java/org/hisp/dhis/android/core/dataelement/DataElementEndpointCall.java b/core/src/main/java/org/hisp/dhis/android/core/dataelement/DataElementEndpointCall.java index bfc9b16f94..62ca4ea52e 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/dataelement/DataElementEndpointCall.java +++ b/core/src/main/java/org/hisp/dhis/android/core/dataelement/DataElementEndpointCall.java @@ -32,33 +32,40 @@ import org.hisp.dhis.android.core.common.GenericEndpointCallImpl; import org.hisp.dhis.android.core.common.GenericHandler; import org.hisp.dhis.android.core.common.Payload; +import org.hisp.dhis.android.core.common.UidsQuery; import org.hisp.dhis.android.core.option.OptionSetHandler; import org.hisp.dhis.android.core.resource.ResourceModel; import java.io.IOException; import java.util.Set; -@SuppressWarnings("PMD") -public class DataElementEndpointCall extends GenericEndpointCallImpl { +import retrofit2.Call; + +public final class DataElementEndpointCall extends GenericEndpointCallImpl { private final DataElementService dataElementService; private DataElementEndpointCall(GenericCallData data, DataElementService dataElementService, - GenericHandler dataElementHandler, - Set uids) { - super(data, dataElementHandler, ResourceModel.Type.DATA_ELEMENT, uids, null); + GenericHandler dataElementHandler, UidsQuery query) { + super(data, dataElementHandler, ResourceModel.Type.DATA_ELEMENT, query); this.dataElementService = dataElementService; } @Override - protected retrofit2.Call> getCall(Set uids, String lastUpdated) - throws IOException { + protected Call> getCall(UidsQuery query, String lastUpdated) throws IOException { return dataElementService.getDataElements(DataElement.allFields, DataElement.lastUpdated.gt(lastUpdated), - DataElement.uid.in(uids), Boolean.FALSE); + DataElement.uid.in(query.uids()), Boolean.FALSE); } - public static DataElementEndpointCall create(GenericCallData data, Set uids) { - return new DataElementEndpointCall(data, data.retrofit().create(DataElementService.class), - DataElementHandler.create(data.databaseAdapter(), - OptionSetHandler.create(data.databaseAdapter())), uids); + public interface Factory { + DataElementEndpointCall create(GenericCallData data, Set uids); } + + public static final DataElementEndpointCall.Factory FACTORY = new DataElementEndpointCall.Factory() { + @Override + public DataElementEndpointCall create(GenericCallData data, Set uids) { + return new DataElementEndpointCall(data, data.retrofit().create(DataElementService.class), + DataElementHandler.create(data.databaseAdapter(), OptionSetHandler.create(data.databaseAdapter())), + UidsQuery.create(uids, null)); + } + }; } \ No newline at end of file diff --git a/core/src/main/java/org/hisp/dhis/android/core/dataelement/DataElementHandler.java b/core/src/main/java/org/hisp/dhis/android/core/dataelement/DataElementHandler.java index 4b0a2c7315..a8472a0540 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/dataelement/DataElementHandler.java +++ b/core/src/main/java/org/hisp/dhis/android/core/dataelement/DataElementHandler.java @@ -27,20 +27,30 @@ */ package org.hisp.dhis.android.core.dataelement; +import org.hisp.dhis.android.core.common.DictionaryTableHandler; import org.hisp.dhis.android.core.common.GenericHandler; -import org.hisp.dhis.android.core.common.GenericHandlerImpl; +import org.hisp.dhis.android.core.common.IdentifiableHandlerImpl; import org.hisp.dhis.android.core.common.IdentifiableObjectStore; +import org.hisp.dhis.android.core.common.ObjectStyle; +import org.hisp.dhis.android.core.common.ObjectStyleHandler; +import org.hisp.dhis.android.core.common.ValueTypeRendering; +import org.hisp.dhis.android.core.common.ValueTypeRenderingHandler; import org.hisp.dhis.android.core.data.database.DatabaseAdapter; import org.hisp.dhis.android.core.option.OptionSet; -import org.hisp.dhis.android.core.option.OptionSetModel; -public class DataElementHandler extends GenericHandlerImpl { - private final GenericHandler optionSetHandler; +public class DataElementHandler extends IdentifiableHandlerImpl { + private final GenericHandler optionSetHandler; + private final DictionaryTableHandler styleHandler; + private final DictionaryTableHandler renderTypeHandler; - DataElementHandler(IdentifiableObjectStore dataSetStore, - GenericHandler optionSetHandler) { - super(dataSetStore); + DataElementHandler(IdentifiableObjectStore dataElementStore, + GenericHandler optionSetHandler, + DictionaryTableHandler styleHandler, + DictionaryTableHandler renderTypeHandler) { + super(dataElementStore); this.optionSetHandler = optionSetHandler; + this.styleHandler = styleHandler; + this.renderTypeHandler = renderTypeHandler; } @Override @@ -49,12 +59,18 @@ protected DataElementModel pojoToModel(DataElement dataElement) { } public static DataElementHandler create(DatabaseAdapter databaseAdapter, - GenericHandler optionSetHandler) { - return new DataElementHandler(DataElementStore.create(databaseAdapter), optionSetHandler); + GenericHandler optionSetHandler) { + return new DataElementHandler( + DataElementStore.create(databaseAdapter), + optionSetHandler, + ObjectStyleHandler.create(databaseAdapter), + ValueTypeRenderingHandler.create(databaseAdapter)); } @Override protected void afterObjectPersisted(DataElement dateElement) { optionSetHandler.handle(dateElement.optionSet()); + styleHandler.handle(dateElement.style(), dateElement.uid(), DataElementModel.TABLE); + renderTypeHandler.handle(dateElement.renderType(), dateElement.uid(), DataElementModel.TABLE); } } \ No newline at end of file diff --git a/core/src/main/java/org/hisp/dhis/android/core/dataelement/DataElementModel.java b/core/src/main/java/org/hisp/dhis/android/core/dataelement/DataElementModel.java index 91ffb2d298..6b5877c80a 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/dataelement/DataElementModel.java +++ b/core/src/main/java/org/hisp/dhis/android/core/dataelement/DataElementModel.java @@ -43,13 +43,11 @@ import org.hisp.dhis.android.core.common.StatementBinder; import org.hisp.dhis.android.core.common.ValueType; import org.hisp.dhis.android.core.data.database.DbValueTypeColumnAdapter; -import org.hisp.dhis.android.core.option.OptionSet; import org.hisp.dhis.android.core.utils.Utils; import static org.hisp.dhis.android.core.utils.StoreUtils.sqLiteBind; @AutoValue -@SuppressWarnings("PMD") public abstract class DataElementModel extends BaseNameableObjectModel implements StatementBinder { public static final String TABLE = "DataElement"; @@ -66,6 +64,8 @@ public static class Columns extends BaseNameableObjectModel.Columns { public static final String OPTION_SET = "optionSet"; public static final String CATEGORY_COMBO = "categoryCombo"; + private Columns() {} + public static String[] all() { return Utils.appendInNewArray(BaseNameableObjectModel.Columns.all(), VALUE_TYPE, ZERO_IS_SIGNIFICANT, AGGREGATION_TYPE, FORM_NAME, NUMBER_TYPE, @@ -86,9 +86,7 @@ public DataElementModel fromCursor(Cursor cursor) { } @Override - @SuppressWarnings("PMD") public DataElementModel fromPojo(DataElement dataElement) { - OptionSet optionSet = dataElement.optionSet(); return DataElementModel.builder() .uid(dataElement.uid()) .code(dataElement.code()) @@ -108,7 +106,7 @@ public DataElementModel fromPojo(DataElement dataElement) { .domainType(dataElement.domainType()) .dimension(dataElement.dimension()) .displayFormName(dataElement.displayFormName()) - .optionSet(optionSet != null ? optionSet.uid() : null) + .optionSet(dataElement.optionSetUid()) .categoryCombo(dataElement.categoryComboUid()) .build(); } diff --git a/core/src/main/java/org/hisp/dhis/android/core/dataelement/DataElementStore.java b/core/src/main/java/org/hisp/dhis/android/core/dataelement/DataElementStore.java index 21df26a54c..c5674dc171 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/dataelement/DataElementStore.java +++ b/core/src/main/java/org/hisp/dhis/android/core/dataelement/DataElementStore.java @@ -32,8 +32,7 @@ import org.hisp.dhis.android.core.common.StoreFactory; import org.hisp.dhis.android.core.data.database.DatabaseAdapter; -@SuppressWarnings("PMD") -public class DataElementStore { +public final class DataElementStore { private DataElementStore() {} diff --git a/core/src/main/java/org/hisp/dhis/android/core/dataelement/DataElementStoreImpl.java b/core/src/main/java/org/hisp/dhis/android/core/dataelement/DataElementStoreImpl.java deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/core/src/main/java/org/hisp/dhis/android/core/dataset/DataSet.java b/core/src/main/java/org/hisp/dhis/android/core/dataset/DataSet.java index 9b5e4484ea..04f7216572 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/dataset/DataSet.java +++ b/core/src/main/java/org/hisp/dhis/android/core/dataset/DataSet.java @@ -35,12 +35,15 @@ import com.google.auto.value.AutoValue; import org.hisp.dhis.android.core.category.CategoryComboModel; +import org.hisp.dhis.android.core.common.Access; import org.hisp.dhis.android.core.common.BaseNameableObject; +import org.hisp.dhis.android.core.common.DataAccess; +import org.hisp.dhis.android.core.common.ObjectStyle; import org.hisp.dhis.android.core.common.ObjectWithUid; -import org.hisp.dhis.android.core.common.PeriodType; import org.hisp.dhis.android.core.data.api.Field; import org.hisp.dhis.android.core.data.api.Fields; import org.hisp.dhis.android.core.data.api.NestedField; +import org.hisp.dhis.android.core.period.PeriodType; import java.util.Date; import java.util.List; @@ -63,6 +66,9 @@ public abstract class DataSet extends BaseNameableObject { private final static String RENDER_AS_TABS = "renderAsTabs"; private final static String RENDER_HORIZONTALLY = "renderHorizontally"; private final static String DATA_SET_ELEMENTS = "dataSetElements"; + private final static String INDICATORS = "indicators"; + private final static String ACCESS = "access"; + private final static String STYLE = "style"; public static final Field uid = Field.create(UID); private static final Field code = Field.create(CODE); @@ -92,6 +98,9 @@ public abstract class DataSet extends BaseNameableObject { private static final Field renderAsTabs = Field.create(RENDER_AS_TABS); private static final Field renderHorizontally = Field.create(RENDER_HORIZONTALLY); private static final NestedField dataSetElements = NestedField.create(DATA_SET_ELEMENTS); + private static final NestedField indicators = NestedField.create(INDICATORS); + private static final NestedField access = NestedField.create(ACCESS); + private static final NestedField style = NestedField.create(STYLE); static final Fields allFields = Fields.builder().fields( uid, code, name, displayName, created, lastUpdated, shortName, displayShortName, @@ -100,7 +109,13 @@ public abstract class DataSet extends BaseNameableObject { expiryDays, timelyDays, notifyCompletingUser, openFuturePeriods, fieldCombinationRequired, validCompleteOnly, noValueRequiresComment, skipOffline, dataElementDecoration, renderAsTabs, renderHorizontally, - dataSetElements.with(DataElementUids.allFields)).build(); + dataSetElements.with(DataElementUids.allFields), + indicators.with(ObjectWithUid.uid), + access.with(Access.data.with(DataAccess.write)), + style.with(ObjectStyle.allFields)).build(); + + static final Fields uidAndAccessRead = Fields.builder().fields( + uid, access.with(Access.data.with(DataAccess.read))).build(); @Nullable @JsonProperty(PERIOD_TYPE) @@ -110,10 +125,9 @@ public abstract class DataSet extends BaseNameableObject { @JsonProperty(CATEGORY_COMBO) public abstract ObjectWithUid categoryCombo(); - @SuppressWarnings("PMD") - public String categoryComboUid() { - return categoryCombo() != null ? categoryCombo().uid() : - CategoryComboModel.DEFAULT_UID; + String categoryComboUid() { + ObjectWithUid combo = categoryCombo(); + return combo == null ? CategoryComboModel.DEFAULT_UID : combo.uid(); } @Nullable @@ -171,6 +185,18 @@ public String categoryComboUid() { @Nullable @JsonProperty(DATA_SET_ELEMENTS) public abstract List dataSetElements(); + + @Nullable + @JsonProperty(INDICATORS) + public abstract List indicators(); + + @Nullable + @JsonProperty(ACCESS) + public abstract Access access(); + + @Nullable + @JsonProperty(STYLE) + public abstract ObjectStyle style(); @JsonCreator public static DataSet create( @@ -200,6 +226,9 @@ public static DataSet create( @JsonProperty(RENDER_AS_TABS) Boolean renderAsTabs, @JsonProperty(RENDER_HORIZONTALLY) Boolean renderHorizontally, @JsonProperty(DATA_SET_ELEMENTS) List dataSetElements, + @JsonProperty(INDICATORS) List indicators, + @JsonProperty(ACCESS) Access access, + @JsonProperty(STYLE) ObjectStyle style, @JsonProperty(DELETED) Boolean deleted) { return new AutoValue_DataSet(uid, code, name, @@ -208,6 +237,7 @@ public static DataSet create( periodType, categoryCombo, mobile, version, expiryDays, timelyDays, notifyCompletingUser, openFuturePeriods, fieldCombinationRequired, validCompleteOnly, noValueRequiresComment, skipOffline, - dataElementDecoration, renderAsTabs, renderHorizontally, dataSetElements); + dataElementDecoration, renderAsTabs, renderHorizontally, dataSetElements, + indicators, access, style); } } diff --git a/core/src/main/java/org/hisp/dhis/android/core/dataset/DataSetAccessEndpointCall.java b/core/src/main/java/org/hisp/dhis/android/core/dataset/DataSetAccessEndpointCall.java new file mode 100644 index 0000000000..2a98b40fdc --- /dev/null +++ b/core/src/main/java/org/hisp/dhis/android/core/dataset/DataSetAccessEndpointCall.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2017, University of Oslo + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.hisp.dhis.android.core.dataset; + +import org.hisp.dhis.android.core.common.BaseEndpointCall; +import org.hisp.dhis.android.core.common.GenericCallData; +import org.hisp.dhis.android.core.common.Payload; +import org.hisp.dhis.android.core.resource.ResourceModel; + +import retrofit2.Response; + +public final class DataSetAccessEndpointCall extends BaseEndpointCall { + private final GenericCallData data; + private final DataSetService dataSetService; + + private DataSetAccessEndpointCall(GenericCallData data, DataSetService dataSetService) { + this.data = data; + this.dataSetService = dataSetService; + } + + @Override + protected Response> callBody() throws Exception { + String lastUpdated = data.resourceHandler().getLastUpdated(ResourceModel.Type.DATA_SET); + return dataSetService.getDataSetsForAccess(DataSet.uidAndAccessRead, DataSet.lastUpdated.gt(lastUpdated), + Boolean.FALSE).execute(); + } + + public interface Factory { + DataSetAccessEndpointCall create(GenericCallData data); + } + + static final DataSetAccessEndpointCall.Factory FACTORY = new DataSetAccessEndpointCall.Factory() { + @Override + public DataSetAccessEndpointCall create(GenericCallData data) { + return new DataSetAccessEndpointCall(data, data.retrofit().create(DataSetService.class)); + } + }; +} \ No newline at end of file diff --git a/core/src/main/java/org/hisp/dhis/android/core/dataset/DataSetDataElementLinkModel.java b/core/src/main/java/org/hisp/dhis/android/core/dataset/DataSetDataElementLinkModel.java index e183a9f857..a353c495d3 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/dataset/DataSetDataElementLinkModel.java +++ b/core/src/main/java/org/hisp/dhis/android/core/dataset/DataSetDataElementLinkModel.java @@ -47,17 +47,18 @@ public abstract class DataSetDataElementLinkModel extends BaseModel implements UpdateWhereStatementBinder { public static final String TABLE = "DataSetDataElementLink"; - @SuppressWarnings("PMD") public static class Columns extends BaseModel.Columns { public static final String DATA_SET = "dataSet"; public static final String DATA_ELEMENT = "dataElement"; + private Columns() {} + public static String[] all() { return Utils.appendInNewArray(BaseModel.Columns.all(), DATA_SET, DATA_ELEMENT); } - public static String[] whereUpdate() { + static String[] whereUpdate() { return new String[]{DATA_SET, DATA_ELEMENT}; } } diff --git a/core/src/main/java/org/hisp/dhis/android/core/dataset/DataSetDataElementLinkStore.java b/core/src/main/java/org/hisp/dhis/android/core/dataset/DataSetDataElementLinkStore.java index e3f36dd8c7..dd1079c9cd 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/dataset/DataSetDataElementLinkStore.java +++ b/core/src/main/java/org/hisp/dhis/android/core/dataset/DataSetDataElementLinkStore.java @@ -32,8 +32,7 @@ import org.hisp.dhis.android.core.common.StoreFactory; import org.hisp.dhis.android.core.data.database.DatabaseAdapter; -@SuppressWarnings("PMD") -public class DataSetDataElementLinkStore { +public final class DataSetDataElementLinkStore { private DataSetDataElementLinkStore() {} diff --git a/core/src/main/java/org/hisp/dhis/android/core/dataset/DataSetEndpointCall.java b/core/src/main/java/org/hisp/dhis/android/core/dataset/DataSetEndpointCall.java index d4933731d0..47c5ac6bca 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/dataset/DataSetEndpointCall.java +++ b/core/src/main/java/org/hisp/dhis/android/core/dataset/DataSetEndpointCall.java @@ -32,30 +32,38 @@ import org.hisp.dhis.android.core.common.GenericEndpointCallImpl; import org.hisp.dhis.android.core.common.GenericHandler; import org.hisp.dhis.android.core.common.Payload; +import org.hisp.dhis.android.core.common.UidsQuery; import org.hisp.dhis.android.core.resource.ResourceModel; import java.io.IOException; import java.util.Set; -@SuppressWarnings("PMD") -public class DataSetEndpointCall extends GenericEndpointCallImpl { +import retrofit2.Call; + +public final class DataSetEndpointCall extends GenericEndpointCallImpl { private final DataSetService dataSetService; private DataSetEndpointCall(GenericCallData data, DataSetService dataSetService, - GenericHandler dataSetHandler, Set uids) { - super(data, dataSetHandler, ResourceModel.Type.DATA_SET, uids, 64); + GenericHandler dataSetHandler, UidsQuery uidsQuery) { + super(data, dataSetHandler, ResourceModel.Type.DATA_SET, uidsQuery); this.dataSetService = dataSetService; } @Override - protected retrofit2.Call> getCall(Set uids, String lastUpdated) - throws IOException { + protected Call> getCall(UidsQuery query, String lastUpdated) throws IOException { return dataSetService.getDataSets(DataSet.allFields, DataSet.lastUpdated.gt(lastUpdated), - DataSet.uid.in(uids), Boolean.FALSE); + DataSet.uid.in(query.uids()), Boolean.FALSE); } - public static DataSetEndpointCall create(GenericCallData data, Set uids) { - return new DataSetEndpointCall(data, data.retrofit().create(DataSetService.class), - DataSetHandler.create(data.databaseAdapter()), uids); + public interface Factory { + DataSetEndpointCall create(GenericCallData data, Set uids); } + + static final DataSetEndpointCall.Factory FACTORY = new DataSetEndpointCall.Factory() { + @Override + public DataSetEndpointCall create(GenericCallData data, Set uids) { + return new DataSetEndpointCall(data, data.retrofit().create(DataSetService.class), + DataSetHandler.create(data.databaseAdapter()), UidsQuery.create(uids, 64)); + } + }; } \ No newline at end of file diff --git a/core/src/main/java/org/hisp/dhis/android/core/dataset/DataSetHandler.java b/core/src/main/java/org/hisp/dhis/android/core/dataset/DataSetHandler.java index f4d760f75d..181b2af1a8 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/dataset/DataSetHandler.java +++ b/core/src/main/java/org/hisp/dhis/android/core/dataset/DataSetHandler.java @@ -27,14 +27,21 @@ */ package org.hisp.dhis.android.core.dataset; -import org.hisp.dhis.android.core.common.GenericHandlerImpl; +import org.hisp.dhis.android.core.common.IdentifiableHandlerImpl; import org.hisp.dhis.android.core.common.IdentifiableObjectStore; +import org.hisp.dhis.android.core.common.DictionaryTableHandler; +import org.hisp.dhis.android.core.common.ObjectStyle; +import org.hisp.dhis.android.core.common.ObjectStyleHandler; import org.hisp.dhis.android.core.data.database.DatabaseAdapter; -public class DataSetHandler extends GenericHandlerImpl { +public class DataSetHandler extends IdentifiableHandlerImpl { - DataSetHandler(IdentifiableObjectStore dataSetStore) { + private final DictionaryTableHandler styleHandler; + + DataSetHandler(IdentifiableObjectStore dataSetStore, + DictionaryTableHandler styleHandler) { super(dataSetStore); + this.styleHandler = styleHandler; } @Override @@ -43,6 +50,13 @@ protected DataSetModel pojoToModel(DataSet dataSet) { } public static DataSetHandler create(DatabaseAdapter databaseAdapter) { - return new DataSetHandler(DataSetStore.create(databaseAdapter)); + return new DataSetHandler( + DataSetStore.create(databaseAdapter), + ObjectStyleHandler.create(databaseAdapter)); + } + + @Override + protected void afterObjectPersisted(DataSet dataSet) { + styleHandler.handle(dataSet.style(), dataSet.uid(), DataSetModel.TABLE); } } diff --git a/core/src/main/java/org/hisp/dhis/android/core/dataset/DataSetModel.java b/core/src/main/java/org/hisp/dhis/android/core/dataset/DataSetModel.java index f97bf73fa1..777b7b360c 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/dataset/DataSetModel.java +++ b/core/src/main/java/org/hisp/dhis/android/core/dataset/DataSetModel.java @@ -39,15 +39,14 @@ import org.hisp.dhis.android.core.common.BaseNameableObjectModel; import org.hisp.dhis.android.core.common.ModelFactory; -import org.hisp.dhis.android.core.common.PeriodType; import org.hisp.dhis.android.core.common.StatementBinder; import org.hisp.dhis.android.core.data.database.DbPeriodTypeColumnAdapter; +import org.hisp.dhis.android.core.period.PeriodType; import org.hisp.dhis.android.core.utils.Utils; import static org.hisp.dhis.android.core.utils.StoreUtils.sqLiteBind; @AutoValue -@SuppressWarnings("PMD") public abstract class DataSetModel extends BaseNameableObjectModel implements StatementBinder { public static final String TABLE = "DataSet"; @@ -68,13 +67,16 @@ public static class Columns extends BaseNameableObjectModel.Columns { public static final String DATA_ELEMENT_DECORATION = "dataElementDecoration"; public static final String RENDER_AS_TABS = "renderAsTabs"; public static final String RENDER_HORIZONTALLY = "renderHorizontally"; + public static final String ACCESS_DATA_WRITE = "accessDataWrite"; + + private Columns() {} public static String[] all() { return Utils.appendInNewArray(BaseNameableObjectModel.Columns.all(), PERIOD_TYPE, CATEGORY_COMBO, MOBILE, VERSION, EXPIRY_DAYS, TIMELY_DAYS, NOTIFY_COMPLETING_USER, OPEN_FUTURE_PERIODS, FIELD_COMBINATION_REQUIRED, VALID_COMPLETE_ONLY, NO_VALUE_REQUIRES_COMMENT, SKIP_OFFLINE, DATA_ELEMENT_DECORATION, - RENDER_AS_TABS, RENDER_HORIZONTALLY); + RENDER_AS_TABS, RENDER_HORIZONTALLY, ACCESS_DATA_WRITE); } } @@ -117,6 +119,7 @@ public DataSetModel fromPojo(DataSet dataSet) { .dataElementDecoration(dataSet.dataElementDecoration()) .renderAsTabs(dataSet.renderAsTabs()) .renderHorizontally(dataSet.renderHorizontally()) + .accessDataWrite(dataSet.access().data().write()) .build(); } }; @@ -186,6 +189,10 @@ public static Builder builder() { @ColumnName(Columns.RENDER_HORIZONTALLY) public abstract Boolean renderHorizontally(); + @Nullable + @ColumnName(Columns.ACCESS_DATA_WRITE) + public abstract Boolean accessDataWrite(); + @Override public void bindToStatement(@NonNull SQLiteStatement sqLiteStatement) { super.bindToStatement(sqLiteStatement); @@ -204,6 +211,7 @@ public void bindToStatement(@NonNull SQLiteStatement sqLiteStatement) { sqLiteBind(sqLiteStatement, 23, dataElementDecoration()); sqLiteBind(sqLiteStatement, 24, renderAsTabs()); sqLiteBind(sqLiteStatement, 25, renderHorizontally()); + sqLiteBind(sqLiteStatement, 26, accessDataWrite()); } @AutoValue.Builder @@ -238,6 +246,8 @@ public static abstract class Builder extends BaseNameableObjectModel.Builder organisationUnits; + private final PeriodHandler periodHandler; - private DataSetParentCall(User user, GenericCallData data, DataSetParentLinkManager linkManager) { + private DataSetParentCall(GenericCallData data, DataSetParentLinkManager linkManager, + DataSetAccessEndpointCall.Factory dataSetAccessCallFactory, + DataSetEndpointCall.Factory dataSetCallFactory, + DataElementEndpointCall.Factory dataElementCallFactory, + IndicatorEndpointCall.Factory indicatorCallFactory, + IndicatorTypeEndpointCall.Factory indicatorTypeCallFactory, + List organisationUnits, + PeriodHandler periodHandler) { super(data); - this.user = user; this.linkManager = linkManager; + this.dataSetAccessCallFactory = dataSetAccessCallFactory; + this.dataSetCallFactory = dataSetCallFactory; + this.dataElementCallFactory = dataElementCallFactory; + this.indicatorCallFactory = indicatorCallFactory; + this.indicatorTypeCallFactory = indicatorTypeCallFactory; + this.organisationUnits = organisationUnits; + this.periodHandler = periodHandler; } @Override public Response callBody() throws Exception { - DataSetEndpointCall dataSetEndpointCall - = DataSetEndpointCall.create(data, getAssignedDataSetUids(user)); + DataSetAccessEndpointCall dataSetAccessEndpointCall = dataSetAccessCallFactory.create(data); + Response> dataSetAccessResponse = dataSetAccessEndpointCall.call(); + List dataSetsWithAccess = dataSetAccessResponse.body().items(); + + Set dataSetUids = DataSetParentUidsHelper.getAssignedDataSetUids(dataSetsWithAccess); + + DataSetEndpointCall dataSetEndpointCall = dataSetCallFactory.create(data, dataSetUids); Response> dataSetResponse = dataSetEndpointCall.call(); List dataSets = dataSetResponse.body().items(); DataElementEndpointCall dataElementEndpointCall = - DataElementEndpointCall.create(data, getDataElementUids(dataSets)); + dataElementCallFactory.create(data, DataSetParentUidsHelper.getDataElementUids(dataSets)); Response> dataElementResponse = dataElementEndpointCall.call(); - linkManager.saveDataSetDataElementLinks(dataSets); - linkManager.saveDataSetOrganisationUnitLinks(user); + IndicatorEndpointCall indicatorEndpointCall + = indicatorCallFactory.create(data, DataSetParentUidsHelper.getIndicatorUids(dataSets)); + Response> indicatorResponse = indicatorEndpointCall.call(); + + List indicators = indicatorResponse.body().items(); + IndicatorTypeEndpointCall indicatorTypeEndpointCall + = indicatorTypeCallFactory.create(data, DataSetParentUidsHelper.getIndicatorTypeUids(indicators)); + indicatorTypeEndpointCall.call(); + + periodHandler.generateAndPersist(); + + linkManager.saveDataSetDataElementAndIndicatorLinks(dataSets); + linkManager.saveDataSetOrganisationUnitLinks(organisationUnits, dataSetUids); return dataElementResponse; } public interface Factory { - Call create(User user, GenericCallData data); + Call create(User user, GenericCallData data, List organisationUnits); } public static final Factory FACTORY = new Factory() { @Override - public Call create(User user, GenericCallData data) { - return new DataSetParentCall(user, data, - DataSetParentLinkManager.create(data.databaseAdapter())); + public Call create(User user, GenericCallData data, List organisationUnits) { + return new DataSetParentCall(data, + DataSetParentLinkManager.create(data.databaseAdapter()), + DataSetAccessEndpointCall.FACTORY, + DataSetEndpointCall.FACTORY, + DataElementEndpointCall.FACTORY, + IndicatorEndpointCall.FACTORY, + IndicatorTypeEndpointCall.FACTORY, + organisationUnits, + PeriodHandler.create(data.databaseAdapter())); } }; } diff --git a/core/src/main/java/org/hisp/dhis/android/core/dataset/DataSetParentLinkManager.java b/core/src/main/java/org/hisp/dhis/android/core/dataset/DataSetParentLinkManager.java index 216f9f6e64..4ed03c0298 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/dataset/DataSetParentLinkManager.java +++ b/core/src/main/java/org/hisp/dhis/android/core/dataset/DataSetParentLinkManager.java @@ -27,39 +27,49 @@ */ package org.hisp.dhis.android.core.dataset; +import org.hisp.dhis.android.core.common.ObjectWithUid; import org.hisp.dhis.android.core.common.ObjectWithoutUidStore; import org.hisp.dhis.android.core.data.database.DatabaseAdapter; +import org.hisp.dhis.android.core.indicator.DataSetIndicatorLinkModel; +import org.hisp.dhis.android.core.indicator.DataSetIndicatorLinkStore; import org.hisp.dhis.android.core.organisationunit.OrganisationUnit; -import org.hisp.dhis.android.core.user.User; import java.util.List; +import java.util.Set; class DataSetParentLinkManager { private final ObjectWithoutUidStore dataSetDataElementStore; private final ObjectWithoutUidStore dataSetOrganisationUnitStore; + private final ObjectWithoutUidStore dataSetIndicatorStore; DataSetParentLinkManager( ObjectWithoutUidStore dataSetDataElementStore, - ObjectWithoutUidStore dataSetOrganisationUnitStore) { + ObjectWithoutUidStore dataSetOrganisationUnitStore, + ObjectWithoutUidStore dataSetIndicatorStore) { this.dataSetDataElementStore = dataSetDataElementStore; this.dataSetOrganisationUnitStore = dataSetOrganisationUnitStore; + this.dataSetIndicatorStore = dataSetIndicatorStore; } static DataSetParentLinkManager create(DatabaseAdapter databaseAdapter) { return new DataSetParentLinkManager( DataSetDataElementLinkStore.create(databaseAdapter), - DataSetOrganisationUnitLinkStore.create(databaseAdapter)); + DataSetOrganisationUnitLinkStore.create(databaseAdapter), + DataSetIndicatorLinkStore.create(databaseAdapter)); } - void saveDataSetDataElementLinks(List dataSets) { + void saveDataSetDataElementAndIndicatorLinks(List dataSets) { for (DataSet dataSet : dataSets) { saveDataSetDataElementLink(dataSet); + saveDataSetIndicatorLink(dataSet); } } private void saveDataSetDataElementLink(DataSet dataSet) { - for (DataElementUids dataSetDataElement : dataSet.dataSetElements()) { - this.dataSetDataElementStore.updateOrInsertWhere( + List dataSetElements = dataSet.dataSetElements(); + assert dataSetElements != null; + for (DataElementUids dataSetDataElement : dataSetElements) { + dataSetDataElementStore.updateOrInsertWhere( DataSetDataElementLinkModel.create( dataSet.uid(), dataSetDataElement.dataElement().uid() @@ -67,23 +77,38 @@ private void saveDataSetDataElementLink(DataSet dataSet) { } } - void saveDataSetOrganisationUnitLinks(User user) { - List organisationUnits = user.organisationUnits(); + private void saveDataSetIndicatorLink(DataSet dataSet) { + List indicators = dataSet.indicators(); + assert indicators != null; + for (ObjectWithUid indicator : indicators) { + dataSetIndicatorStore.updateOrInsertWhere( + DataSetIndicatorLinkModel.create( + dataSet.uid(), + indicator.uid() + )); + } + } + void saveDataSetOrganisationUnitLinks(List organisationUnits, Set dataSetUids) { if (organisationUnits != null) { for (OrganisationUnit organisationUnit : organisationUnits) { - saveDataSetOrganisationUnitLink(organisationUnit); + saveDataSetOrganisationUnitLink(organisationUnit, dataSetUids); + } } } - private void saveDataSetOrganisationUnitLink(OrganisationUnit organisationUnit) { - for (DataSet dataSet : organisationUnit.dataSets()) { - this.dataSetOrganisationUnitStore.updateOrInsertWhere( - DataSetOrganisationUnitLinkModel.create( - dataSet.uid(), - organisationUnit.uid() - )); + private void saveDataSetOrganisationUnitLink(OrganisationUnit organisationUnit, Set dataSetUids) { + List orgUnitDataSets = organisationUnit.dataSets(); + assert orgUnitDataSets != null; + for (DataSet dataSet : orgUnitDataSets) { + if (dataSetUids.contains(dataSet.uid())) { + dataSetOrganisationUnitStore.updateOrInsertWhere( + DataSetOrganisationUnitLinkModel.create( + dataSet.uid(), + organisationUnit.uid() + )); + } } } } \ No newline at end of file diff --git a/core/src/main/java/org/hisp/dhis/android/core/dataset/DataSetParentUidsHelper.java b/core/src/main/java/org/hisp/dhis/android/core/dataset/DataSetParentUidsHelper.java index 58e7c0e6a6..a96bb9ad63 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/dataset/DataSetParentUidsHelper.java +++ b/core/src/main/java/org/hisp/dhis/android/core/dataset/DataSetParentUidsHelper.java @@ -27,66 +27,58 @@ */ package org.hisp.dhis.android.core.dataset; -import org.hisp.dhis.android.core.organisationunit.OrganisationUnit; -import org.hisp.dhis.android.core.user.User; -import org.hisp.dhis.android.core.user.UserRole; +import org.hisp.dhis.android.core.common.Access; +import org.hisp.dhis.android.core.common.ObjectWithUid; +import org.hisp.dhis.android.core.indicator.Indicator; import java.util.HashSet; import java.util.List; import java.util.Set; - -@SuppressWarnings("PMD") -class DataSetParentUidsHelper { +final class DataSetParentUidsHelper { private DataSetParentUidsHelper() {} - static Set getAssignedDataSetUids(User user) { - if (user == null || user.userCredentials() == null || user.userCredentials().userRoles() == null) { - return null; - } - + static Set getAssignedDataSetUids(List dataSetsWithAccess) { Set dataSetUids = new HashSet<>(); - - getDataSetUidsFromUserRoles(user, dataSetUids); - getDataSetUidsFromOrganisationUnits(user, dataSetUids); - - return dataSetUids; - } - - private static void getDataSetUidsFromOrganisationUnits(User user, Set dataSetUids) { - List organisationUnits = user.organisationUnits(); - - if (organisationUnits != null) { - for (OrganisationUnit organisationUnit : organisationUnits) { - addDataSets(organisationUnit.dataSets(), dataSetUids); + for (DataSet dataSet: dataSetsWithAccess) { + Access access = dataSet.access(); + if (access != null && access.data().read()) { + dataSetUids.add(dataSet.uid()); } } - } - private static void getDataSetUidsFromUserRoles(User user, Set dataSetUids) { - List userRoles = user.userCredentials().userRoles(); + return dataSetUids; + } - if (userRoles != null) { - for (UserRole userRole : userRoles) { - addDataSets(userRole.dataSets(), dataSetUids); + static Set getDataElementUids(List dataSets) { + Set uids = new HashSet<>(); + for (DataSet dataSet : dataSets) { + List dataSetElements = dataSet.dataSetElements(); + assert dataSetElements != null; + for (DataElementUids dataSetElement : dataSetElements) { + uids.add(dataSetElement.dataElement().uid()); } } + return uids; } - private static void addDataSets(List dataSets, Set dataSetUids) { - if (dataSets != null) { - for (DataSet dataSet : dataSets) { - dataSetUids.add(dataSet.uid()); + static Set getIndicatorUids(List dataSets) { + Set uids = new HashSet<>(); + for (DataSet dataSet : dataSets) { + for (ObjectWithUid indicator : dataSet.indicators()) { + uids.add(indicator.uid()); } } + return uids; } - static Set getDataElementUids(List dataSets) { + static Set getIndicatorTypeUids(List indicators) { Set uids = new HashSet<>(); - for (DataSet dataSet : dataSets) { - for (DataElementUids dataSetElement : dataSet.dataSetElements()) { - uids.add(dataSetElement.dataElement().uid()); + for (Indicator indicator : indicators) { + ObjectWithUid type = indicator.indicatorType(); + if (type != null) { + uids.add(type.uid()); } } return uids; diff --git a/core/src/main/java/org/hisp/dhis/android/core/dataset/DataSetService.java b/core/src/main/java/org/hisp/dhis/android/core/dataset/DataSetService.java index 49c510d29b..fdb7d45f08 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/dataset/DataSetService.java +++ b/core/src/main/java/org/hisp/dhis/android/core/dataset/DataSetService.java @@ -44,4 +44,8 @@ Call> getDataSets(@Query("fields") @Which Fields field @Query("filter") @Where Filter uids, @Query("paging") Boolean paging); + @GET("dataSets") + Call> getDataSetsForAccess(@Query("fields") @Which Fields fields, + @Query("filter") @Where Filter lastUpdated, + @Query("paging") Boolean paging); } diff --git a/core/src/main/java/org/hisp/dhis/android/core/dataset/DataSetStore.java b/core/src/main/java/org/hisp/dhis/android/core/dataset/DataSetStore.java index 0584f153df..6d0dc1ca04 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/dataset/DataSetStore.java +++ b/core/src/main/java/org/hisp/dhis/android/core/dataset/DataSetStore.java @@ -32,8 +32,7 @@ import org.hisp.dhis.android.core.common.StoreFactory; import org.hisp.dhis.android.core.data.database.DatabaseAdapter; -@SuppressWarnings("PMD") -public class DataSetStore { +public final class DataSetStore { private DataSetStore() {} diff --git a/core/src/main/java/org/hisp/dhis/android/core/datavalue/DataValue.java b/core/src/main/java/org/hisp/dhis/android/core/datavalue/DataValue.java new file mode 100644 index 0000000000..3e7016e5d2 --- /dev/null +++ b/core/src/main/java/org/hisp/dhis/android/core/datavalue/DataValue.java @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2017, University of Oslo + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.hisp.dhis.android.core.datavalue; + +import android.support.annotation.Nullable; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.auto.value.AutoValue; + +import org.hisp.dhis.android.core.data.api.Field; +import org.hisp.dhis.android.core.data.api.Fields; + +import java.util.Date; + +@AutoValue +public abstract class DataValue { + private static final String DATA_ELEMENT = "dataElement"; + private static final String PERIOD = "period"; + private static final String ORGANISATION_UNIT = "orgUnit"; + private static final String CATEGORY_OPTION_COMBO = "categoryOptionCombo"; + private static final String ATTRIBUTE_OPTION_COMBO = "attributeOptionCombo"; + private static final String VALUE = "value"; + private static final String STORED_BY = "storedBy"; + private static final String CREATED = "created"; + private static final String LAST_UPDATED = "lastUpdated"; + private static final String COMMENT = "comment"; + private static final String FOLLOW_UP = "followUp"; + private static final String DELETED = "deleted"; + + private static final Field dataElement = Field.create(DATA_ELEMENT); + private static final Field period = Field.create(PERIOD); + private static final Field organisationUnit = Field.create(ORGANISATION_UNIT); + private static final Field categoryOptionCombo = Field.create(CATEGORY_OPTION_COMBO); + private static final Field attributeOptionCombo = Field.create(ATTRIBUTE_OPTION_COMBO); + private static final Field value = Field.create(VALUE); + private static final Field storedBy = Field.create(STORED_BY); + private static final Field created = Field.create(CREATED); + static final Field lastUpdated = Field.create(LAST_UPDATED); + private static final Field comment = Field.create(COMMENT); + private static final Field followUp = Field.create(FOLLOW_UP); + private static final Field deleted = Field.create(DELETED); + + static final Fields allFields = Fields.builder().fields( + dataElement, period, organisationUnit, categoryOptionCombo, attributeOptionCombo, + value, storedBy, created, lastUpdated, comment, followUp, deleted).build(); + + @Nullable + @JsonProperty(DATA_ELEMENT) + public abstract String dataElement(); + + @Nullable + @JsonProperty(PERIOD) + public abstract String period(); + + @Nullable + @JsonProperty(ORGANISATION_UNIT) + public abstract String organisationUnit(); + + @Nullable + @JsonProperty(CATEGORY_OPTION_COMBO) + public abstract String categoryOptionCombo(); + + @Nullable + @JsonProperty(ATTRIBUTE_OPTION_COMBO) + public abstract String attributeOptionCombo(); + + @Nullable + @JsonProperty(VALUE) + public abstract String value(); + + @Nullable + @JsonProperty(STORED_BY) + public abstract String storedBy(); + + @Nullable + @JsonProperty(CREATED) + public abstract Date created(); + + @Nullable + @JsonProperty(LAST_UPDATED) + public abstract Date lastUpdated(); + + @Nullable + @JsonProperty(COMMENT) + public abstract String comment(); + + @Nullable + @JsonProperty(FOLLOW_UP) + public abstract Boolean followUp(); + + @Nullable + @JsonProperty(DELETED) + public abstract Boolean deleted(); + + @JsonCreator + public static DataValue create( + @JsonProperty(DATA_ELEMENT) String dataElement, + @JsonProperty(PERIOD) String period, + @JsonProperty(ORGANISATION_UNIT) String organisationUnit, + @JsonProperty(CATEGORY_OPTION_COMBO) String categoryOptionCombo, + @JsonProperty(ATTRIBUTE_OPTION_COMBO) String attributeOptionCombo, + @JsonProperty(VALUE) String value, + @JsonProperty(STORED_BY) String storedBy, + @JsonProperty(CREATED) Date created, + @JsonProperty(LAST_UPDATED) Date lastUpdated, + @JsonProperty(COMMENT) String comment, + @JsonProperty(FOLLOW_UP) Boolean followUp, + @JsonProperty(DELETED) Boolean deleted) { + + return new AutoValue_DataValue(dataElement, period, organisationUnit, categoryOptionCombo, + attributeOptionCombo, value, storedBy, created, lastUpdated, comment, followUp, deleted); + } +} diff --git a/core/src/main/java/org/hisp/dhis/android/core/datavalue/DataValueEndpointCall.java b/core/src/main/java/org/hisp/dhis/android/core/datavalue/DataValueEndpointCall.java new file mode 100644 index 0000000000..63cf39211c --- /dev/null +++ b/core/src/main/java/org/hisp/dhis/android/core/datavalue/DataValueEndpointCall.java @@ -0,0 +1,76 @@ +/* * Copyright (c) 2017, University of Oslo + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/ + +package org.hisp.dhis.android.core.datavalue; + +import org.hisp.dhis.android.core.common.GenericCallData; +import org.hisp.dhis.android.core.common.GenericEndpointCallImpl; +import org.hisp.dhis.android.core.common.GenericHandler; +import org.hisp.dhis.android.core.common.Payload; +import org.hisp.dhis.android.core.resource.ResourceModel; + +import java.io.IOException; +import java.util.Set; + +import retrofit2.Call; + +import static org.hisp.dhis.android.core.utils.Utils.commaSeparatedArrayValuesFromSet; + +public final class DataValueEndpointCall extends GenericEndpointCallImpl { + private final DataValueService dataValueService; + + private DataValueEndpointCall(GenericCallData data, DataValueService dataValueService, + GenericHandler dataValueHandler, DataValueQuery query) { + super(data, dataValueHandler, ResourceModel.Type.DATA_VALUE, query); + this.dataValueService = dataValueService; + } + + @Override + protected Call> getCall(DataValueQuery query, String lastUpdated) throws IOException { + return dataValueService.getDataValues( + DataValue.allFields, + DataValue.lastUpdated.gt(lastUpdated), + commaSeparatedArrayValuesFromSet(query.dataSetUids()), + commaSeparatedArrayValuesFromSet(query.periodIds()), + commaSeparatedArrayValuesFromSet(query.orgUnitUids()), + Boolean.FALSE); + } + + public interface Factory { + DataValueEndpointCall create(GenericCallData data, Set dataSetUids, Set periodIds, + Set orgUnitUids); + } + + public static final DataValueEndpointCall.Factory FACTORY = new DataValueEndpointCall.Factory() { + @Override + public DataValueEndpointCall create(GenericCallData data, Set dataSetUids, Set periodIds, + Set orgUnitUids) { + return new DataValueEndpointCall(data, data.retrofit().create(DataValueService.class), + DataValueHandler.create(data.databaseAdapter()), DataValueQuery.create(dataSetUids, periodIds, + orgUnitUids)); + } + }; +} diff --git a/core/src/main/java/org/hisp/dhis/android/core/datavalue/DataValueHandler.java b/core/src/main/java/org/hisp/dhis/android/core/datavalue/DataValueHandler.java new file mode 100644 index 0000000000..816d75684c --- /dev/null +++ b/core/src/main/java/org/hisp/dhis/android/core/datavalue/DataValueHandler.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2017, University of Oslo + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.hisp.dhis.android.core.datavalue; + +import org.hisp.dhis.android.core.common.ObjectWithoutUidHandlerImpl; +import org.hisp.dhis.android.core.common.ObjectWithoutUidStore; +import org.hisp.dhis.android.core.data.database.DatabaseAdapter; + +public class DataValueHandler extends ObjectWithoutUidHandlerImpl { + + DataValueHandler(ObjectWithoutUidStore dataValueStore) { + super(dataValueStore); + } + + protected DataValueModel pojoToModel(DataValue dataValue) { + return DataValueModel.factory.fromPojo(dataValue); + } + + public static DataValueHandler create(DatabaseAdapter databaseAdapter) { + return new DataValueHandler(DataValueStore.create(databaseAdapter)); + } +} diff --git a/core/src/main/java/org/hisp/dhis/android/core/datavalue/DataValueModel.java b/core/src/main/java/org/hisp/dhis/android/core/datavalue/DataValueModel.java new file mode 100644 index 0000000000..897b9cc2e6 --- /dev/null +++ b/core/src/main/java/org/hisp/dhis/android/core/datavalue/DataValueModel.java @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2017, University of Oslo + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.hisp.dhis.android.core.datavalue; + +import android.database.Cursor; +import android.database.sqlite.SQLiteStatement; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import com.gabrielittner.auto.value.cursor.ColumnAdapter; +import com.gabrielittner.auto.value.cursor.ColumnName; +import com.google.auto.value.AutoValue; + +import org.hisp.dhis.android.core.common.BaseModel; +import org.hisp.dhis.android.core.common.ModelFactory; +import org.hisp.dhis.android.core.common.UpdateWhereStatementBinder; +import org.hisp.dhis.android.core.data.database.DbDateColumnAdapter; +import org.hisp.dhis.android.core.utils.Utils; + +import java.util.Date; + +import static org.hisp.dhis.android.core.utils.StoreUtils.sqLiteBind; + +@AutoValue +public abstract class DataValueModel extends BaseModel implements UpdateWhereStatementBinder { + + public static final String TABLE = "DataValue"; + + public static class Columns extends BaseModel.Columns { + public static final String DATA_ELEMENT = "dataElement"; + public static final String PERIOD = "period"; + public static final String ORGANISATION_UNIT = "organisationUnit"; + public static final String CATEGORY_OPTION_COMBO = "categoryOptionCombo"; + public static final String ATTRIBUTE_OPTION_COMBO = "attributeOptionCombo"; + public static final String VALUE = "value"; + public static final String STORED_BY = "storedBy"; + public static final String CREATED = "created"; + public static final String LAST_UPDATED = "lastUpdated"; + public static final String COMMENT = "comment"; + public static final String FOLLOW_UP = "followUp"; + + private Columns() {} + + public static String[] all() { + return Utils.appendInNewArray(BaseModel.Columns.all(), + DATA_ELEMENT, PERIOD, ORGANISATION_UNIT, CATEGORY_OPTION_COMBO, + ATTRIBUTE_OPTION_COMBO, VALUE, STORED_BY, CREATED, LAST_UPDATED, COMMENT, FOLLOW_UP); + } + + public static String[] whereUpdate() { + return new String[]{DATA_ELEMENT, PERIOD, ORGANISATION_UNIT, CATEGORY_OPTION_COMBO, + ATTRIBUTE_OPTION_COMBO}; + } + } + + static DataValueModel create(Cursor cursor) { + return AutoValue_DataValueModel.createFromCursor(cursor); + } + + public static final ModelFactory factory + = new ModelFactory() { + @Override + public DataValueModel fromCursor(Cursor cursor) { + return create(cursor); + } + + @Override + public DataValueModel fromPojo(DataValue dataValue) { + return DataValueModel.builder() + .dataElement(dataValue.dataElement()) + .period(dataValue.period()) + .organisationUnit(dataValue.organisationUnit()) + .categoryOptionCombo(dataValue.categoryOptionCombo()) + .attributeOptionCombo(dataValue.attributeOptionCombo()) + .value(dataValue.value()) + .storedBy(dataValue.storedBy()) + .created(dataValue.created()) + .lastUpdated(dataValue.lastUpdated()) + .comment(dataValue.comment()) + .followUp(dataValue.followUp()) + .build(); + } + }; + + public static Builder builder() { + return new $AutoValue_DataValueModel.Builder(); + } + + @Nullable + @ColumnName(Columns.DATA_ELEMENT) + public abstract String dataElement(); + + @Nullable + @ColumnName(Columns.PERIOD) + public abstract String period(); + + @Nullable + @ColumnName(Columns.ORGANISATION_UNIT) + public abstract String organisationUnit(); + + @Nullable + @ColumnName(Columns.CATEGORY_OPTION_COMBO) + public abstract String categoryOptionCombo(); + + @Nullable + @ColumnName(Columns.ATTRIBUTE_OPTION_COMBO) + public abstract String attributeOptionCombo(); + + @Nullable + @ColumnName(Columns.VALUE) + public abstract String value(); + + @Nullable + @ColumnName(Columns.STORED_BY) + public abstract String storedBy(); + + @Nullable + @ColumnName(Columns.CREATED) + @ColumnAdapter(DbDateColumnAdapter.class) + public abstract Date created(); + + @Nullable + @ColumnName(Columns.LAST_UPDATED) + @ColumnAdapter(DbDateColumnAdapter.class) + public abstract Date lastUpdated(); + + @Nullable + @ColumnName(Columns.COMMENT) + public abstract String comment(); + + @Nullable + @ColumnName(Columns.FOLLOW_UP) + public abstract Boolean followUp(); + + @Override + public void bindToStatement(@NonNull SQLiteStatement sqLiteStatement) { + sqLiteBind(sqLiteStatement, 1, dataElement()); + sqLiteBind(sqLiteStatement, 2, period()); + sqLiteBind(sqLiteStatement, 3, organisationUnit()); + sqLiteBind(sqLiteStatement, 4, categoryOptionCombo()); + sqLiteBind(sqLiteStatement, 5, attributeOptionCombo()); + sqLiteBind(sqLiteStatement, 6, value()); + sqLiteBind(sqLiteStatement, 7, storedBy()); + sqLiteBind(sqLiteStatement, 8, created()); + sqLiteBind(sqLiteStatement, 9, lastUpdated()); + sqLiteBind(sqLiteStatement, 10, comment()); + sqLiteBind(sqLiteStatement, 11, followUp()); + } + + @Override + public void bindToUpdateWhereStatement(@NonNull SQLiteStatement sqLiteStatement) { + sqLiteBind(sqLiteStatement, 12, dataElement()); + sqLiteBind(sqLiteStatement, 13, period()); + sqLiteBind(sqLiteStatement, 14, organisationUnit()); + sqLiteBind(sqLiteStatement, 15, categoryOptionCombo()); + sqLiteBind(sqLiteStatement, 16, attributeOptionCombo()); + } + + @AutoValue.Builder + public static abstract class Builder extends BaseModel.Builder { + public abstract Builder dataElement(String dataElement); + + public abstract Builder period(String period); + + public abstract Builder organisationUnit(String organisationUnit); + + public abstract Builder categoryOptionCombo(String categoryOptionCombo); + + public abstract Builder attributeOptionCombo(String attributeOptionCombo); + + public abstract Builder value(String value); + + public abstract Builder storedBy(String storedBy); + + public abstract Builder created(Date created); + + public abstract Builder lastUpdated(Date lastUpdated); + + public abstract Builder comment(String comment); + + public abstract Builder followUp(Boolean followUp); + + public abstract DataValueModel build(); + } +} \ No newline at end of file diff --git a/core/src/main/java/org/hisp/dhis/android/core/datavalue/DataValueQuery.java b/core/src/main/java/org/hisp/dhis/android/core/datavalue/DataValueQuery.java new file mode 100644 index 0000000000..a7e9c08f8a --- /dev/null +++ b/core/src/main/java/org/hisp/dhis/android/core/datavalue/DataValueQuery.java @@ -0,0 +1,21 @@ +package org.hisp.dhis.android.core.datavalue; + +import com.google.auto.value.AutoValue; + +import org.hisp.dhis.android.core.common.BaseQuery; + +import java.util.Set; + +@AutoValue +public abstract class DataValueQuery extends BaseQuery { + public abstract Set dataSetUids(); + + public abstract Set periodIds(); + + public abstract Set orgUnitUids(); + + public static DataValueQuery create(Set dataSetUids, Set periodIds, Set orgUnitUids) { + return new AutoValue_DataValueQuery(1, BaseQuery.DEFAULT_PAGE_SIZE, false, + dataSetUids, periodIds, orgUnitUids); + } +} diff --git a/core/src/main/java/org/hisp/dhis/android/core/datavalue/DataValueService.java b/core/src/main/java/org/hisp/dhis/android/core/datavalue/DataValueService.java new file mode 100644 index 0000000000..64fc8dca3b --- /dev/null +++ b/core/src/main/java/org/hisp/dhis/android/core/datavalue/DataValueService.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2017, University of Oslo + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.hisp.dhis.android.core.datavalue; + +import org.hisp.dhis.android.core.common.Payload; +import org.hisp.dhis.android.core.data.api.Fields; +import org.hisp.dhis.android.core.data.api.Filter; +import org.hisp.dhis.android.core.data.api.Where; +import org.hisp.dhis.android.core.data.api.Which; + +import retrofit2.Call; +import retrofit2.http.GET; +import retrofit2.http.Query; + +public interface DataValueService { + @GET("dataValueSets") + Call> getDataValues(@Query("fields") @Which Fields fields, + @Query("filter") @Where Filter lastUpdated, + @Query("dataSet") @Where String dataSetUids, + @Query("period") @Where String periodIds, + @Query("orgUnit") @Where String orgUnitUids, + @Query("paging") Boolean paging); +} \ No newline at end of file diff --git a/core/src/main/java/org/hisp/dhis/android/core/datavalue/DataValueStore.java b/core/src/main/java/org/hisp/dhis/android/core/datavalue/DataValueStore.java new file mode 100644 index 0000000000..80d39925df --- /dev/null +++ b/core/src/main/java/org/hisp/dhis/android/core/datavalue/DataValueStore.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2017, University of Oslo + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.hisp.dhis.android.core.datavalue; + +import org.hisp.dhis.android.core.common.ObjectWithoutUidStore; +import org.hisp.dhis.android.core.common.StoreFactory; +import org.hisp.dhis.android.core.data.database.DatabaseAdapter; + +public final class DataValueStore { + + private DataValueStore() {} + + public static ObjectWithoutUidStore create(DatabaseAdapter databaseAdapter) { + return StoreFactory.objectWithoutUidStore(databaseAdapter, DataValueModel.TABLE, + DataValueModel.Columns.all(), DataValueModel.Columns.whereUpdate()); + } +} \ No newline at end of file diff --git a/core/src/main/java/org/hisp/dhis/android/core/indicator/DataSetIndicatorLinkModel.java b/core/src/main/java/org/hisp/dhis/android/core/indicator/DataSetIndicatorLinkModel.java new file mode 100644 index 0000000000..2530c44f17 --- /dev/null +++ b/core/src/main/java/org/hisp/dhis/android/core/indicator/DataSetIndicatorLinkModel.java @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2017, University of Oslo + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.hisp.dhis.android.core.indicator; + +import android.content.ContentValues; +import android.database.Cursor; +import android.database.sqlite.SQLiteStatement; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import com.gabrielittner.auto.value.cursor.ColumnName; +import com.google.auto.value.AutoValue; + +import org.hisp.dhis.android.core.common.BaseModel; +import org.hisp.dhis.android.core.common.LinkModelFactory; +import org.hisp.dhis.android.core.common.UpdateWhereStatementBinder; +import org.hisp.dhis.android.core.utils.Utils; + +import static org.hisp.dhis.android.core.utils.StoreUtils.sqLiteBind; + +@AutoValue +public abstract class DataSetIndicatorLinkModel extends BaseModel implements UpdateWhereStatementBinder { + public static final String TABLE = "DataSetIndicatorLink"; + + public abstract static class Columns extends BaseModel.Columns { + public static final String DATA_SET = "dataSet"; + public static final String INDICATOR = "indicator"; + + public static String[] all() { + return Utils.appendInNewArray(BaseModel.Columns.all(), + DATA_SET, INDICATOR); + } + + static String[] whereUpdate() { + return new String[]{DATA_SET, INDICATOR}; + } + } + + public static DataSetIndicatorLinkModel create(Cursor cursor) { + return AutoValue_DataSetIndicatorLinkModel.createFromCursor(cursor); + } + + public static final LinkModelFactory factory + = new LinkModelFactory() { + @Override + public DataSetIndicatorLinkModel fromCursor(Cursor cursor) { + return create(cursor); + } + }; + + public static DataSetIndicatorLinkModel create( + String dataSetUid, String indicatorUid) { + return DataSetIndicatorLinkModel.builder() + .dataSet(dataSetUid) + .indicator(indicatorUid) + .build(); + } + + public static Builder builder() { + return new $$AutoValue_DataSetIndicatorLinkModel.Builder(); + } + + @Nullable + @ColumnName(Columns.DATA_SET) + public abstract String dataSet(); + + @Nullable + @ColumnName(Columns.INDICATOR) + public abstract String indicator(); + + @NonNull + public abstract ContentValues toContentValues(); + + @Override + public void bindToStatement(@NonNull SQLiteStatement sqLiteStatement) { + sqLiteBind(sqLiteStatement, 1, dataSet()); + sqLiteBind(sqLiteStatement, 2, indicator()); + } + + @Override + public void bindToUpdateWhereStatement(@NonNull SQLiteStatement sqLiteStatement) { + sqLiteBind(sqLiteStatement, 3, dataSet()); + sqLiteBind(sqLiteStatement, 4, indicator()); + } + + @AutoValue.Builder + public static abstract class Builder extends BaseModel.Builder { + public abstract Builder dataSet(String dataSet); + + public abstract Builder indicator(String indicator); + + public abstract DataSetIndicatorLinkModel build(); + } +} diff --git a/core/src/main/java/org/hisp/dhis/android/core/indicator/DataSetIndicatorLinkStore.java b/core/src/main/java/org/hisp/dhis/android/core/indicator/DataSetIndicatorLinkStore.java new file mode 100644 index 0000000000..f39408fde3 --- /dev/null +++ b/core/src/main/java/org/hisp/dhis/android/core/indicator/DataSetIndicatorLinkStore.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2017, University of Oslo + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.hisp.dhis.android.core.indicator; + +import org.hisp.dhis.android.core.common.ObjectWithoutUidStore; +import org.hisp.dhis.android.core.common.StoreFactory; +import org.hisp.dhis.android.core.data.database.DatabaseAdapter; + +public final class DataSetIndicatorLinkStore { + + private DataSetIndicatorLinkStore() {} + + public static ObjectWithoutUidStore create(DatabaseAdapter databaseAdapter) { + return StoreFactory.objectWithoutUidStore(databaseAdapter, DataSetIndicatorLinkModel.TABLE, + DataSetIndicatorLinkModel.Columns.all(), DataSetIndicatorLinkModel.Columns.whereUpdate()); + } +} \ No newline at end of file diff --git a/core/src/main/java/org/hisp/dhis/android/core/indicator/Indicator.java b/core/src/main/java/org/hisp/dhis/android/core/indicator/Indicator.java new file mode 100644 index 0000000000..39b8c6efef --- /dev/null +++ b/core/src/main/java/org/hisp/dhis/android/core/indicator/Indicator.java @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2017, University of Oslo + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.hisp.dhis.android.core.indicator; + +import android.support.annotation.Nullable; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.auto.value.AutoValue; + +import org.hisp.dhis.android.core.common.BaseNameableObject; +import org.hisp.dhis.android.core.common.ObjectWithUid; +import org.hisp.dhis.android.core.data.api.Field; +import org.hisp.dhis.android.core.data.api.Fields; + +import java.util.Date; + +@AutoValue +public abstract class Indicator extends BaseNameableObject { + private final static String ANNUALIZED = "annualized"; + private final static String INDICATOR_TYPE = "indicatorType"; + private final static String NUMERATOR = "numerator"; + private final static String NUMERATOR_DESCRIPTION = "numeratorDescription"; + private final static String DENOMINATOR = "denominator"; + private final static String DENOMINATOR_DESCRIPTION = "denominatorDescription"; + private final static String URL = "url"; + + static final Field uid = Field.create(UID); + private static final Field code = Field.create(CODE); + private static final Field name = Field.create(NAME); + private static final Field displayName = Field.create(DISPLAY_NAME); + private static final Field created = Field.create(CREATED); + static final Field lastUpdated = Field.create(LAST_UPDATED); + private static final Field shortName = Field.create(SHORT_NAME); + private static final Field displayShortName = Field.create(DISPLAY_SHORT_NAME); + private static final Field description = Field.create(DESCRIPTION); + private static final Field displayDescription = Field.create(DISPLAY_DESCRIPTION); + private static final Field deleted = Field.create(DELETED); + + private static final Field annualized = Field.create(ANNUALIZED); + private static final Field indicatorType = Field.create(INDICATOR_TYPE); + private static final Field numerator = Field.create(NUMERATOR); + private static final Field numeratorDescription = Field.create(NUMERATOR_DESCRIPTION); + private static final Field denominator = Field.create(DENOMINATOR); + private static final Field denominatorDescription = Field.create(DENOMINATOR_DESCRIPTION); + private static final Field url = Field.create(URL); + + static final Fields allFields = Fields.builder().fields( + uid, code, name, displayName, created, lastUpdated, shortName, displayShortName, + description, displayDescription, deleted, + annualized, indicatorType, numerator, numeratorDescription, denominator, + denominatorDescription, url).build(); + + @Nullable + @JsonProperty(ANNUALIZED) + abstract Boolean annualized(); + + @Nullable + @JsonProperty(INDICATOR_TYPE) + public abstract ObjectWithUid indicatorType(); + + String indicatorTypeUid() { + ObjectWithUid type = indicatorType(); + return type == null ? null : type.uid(); + } + + @Nullable + @JsonProperty(NUMERATOR) + abstract String numerator(); + + @Nullable + @JsonProperty(NUMERATOR_DESCRIPTION) + abstract String numeratorDescription(); + + @Nullable + @JsonProperty(DENOMINATOR) + abstract String denominator(); + + @Nullable + @JsonProperty(DENOMINATOR_DESCRIPTION) + abstract String denominatorDescription(); + + @Nullable + @JsonProperty(URL) + abstract String url(); + + @JsonCreator + static Indicator create( + @JsonProperty(UID) String uid, + @JsonProperty(CODE) String code, + @JsonProperty(NAME) String name, + @JsonProperty(DISPLAY_NAME) String displayName, + @JsonProperty(CREATED) Date created, + @JsonProperty(LAST_UPDATED) Date lastUpdated, + @JsonProperty(SHORT_NAME) String shortName, + @JsonProperty(DISPLAY_SHORT_NAME) String displayShortName, + @JsonProperty(DESCRIPTION) String description, + @JsonProperty(DISPLAY_DESCRIPTION) String displayDescription, + @JsonProperty(ANNUALIZED) Boolean annualized, + @JsonProperty(INDICATOR_TYPE) ObjectWithUid indicatorType, + @JsonProperty(NUMERATOR) String numerator, + @JsonProperty(NUMERATOR_DESCRIPTION) String numeratorDescription, + @JsonProperty(DENOMINATOR) String denominator, + @JsonProperty(DENOMINATOR_DESCRIPTION) String denominatorDescription, + @JsonProperty(URL) String url, + @JsonProperty(DELETED) Boolean deleted) { + + return new AutoValue_Indicator(uid, code, name, + displayName, created, lastUpdated, deleted, + shortName, displayShortName, description, displayDescription, + annualized, indicatorType, numerator, numeratorDescription, denominator, + denominatorDescription, url); + } +} diff --git a/core/src/main/java/org/hisp/dhis/android/core/indicator/IndicatorEndpointCall.java b/core/src/main/java/org/hisp/dhis/android/core/indicator/IndicatorEndpointCall.java new file mode 100644 index 0000000000..fdd0e7ec4c --- /dev/null +++ b/core/src/main/java/org/hisp/dhis/android/core/indicator/IndicatorEndpointCall.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2017, University of Oslo + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.hisp.dhis.android.core.indicator; + +import org.hisp.dhis.android.core.common.GenericCallData; +import org.hisp.dhis.android.core.common.GenericEndpointCallImpl; +import org.hisp.dhis.android.core.common.GenericHandler; +import org.hisp.dhis.android.core.common.Payload; +import org.hisp.dhis.android.core.common.UidsQuery; +import org.hisp.dhis.android.core.resource.ResourceModel; + +import java.io.IOException; +import java.util.Set; + +public final class IndicatorEndpointCall extends GenericEndpointCallImpl { + private final IndicatorService indicatorService; + + private IndicatorEndpointCall(GenericCallData data, IndicatorService indicatorService, + GenericHandler indicatorHandler, UidsQuery uidsQuery) { + super(data, indicatorHandler, ResourceModel.Type.INDICATOR, uidsQuery); + this.indicatorService = indicatorService; + } + + @Override + protected retrofit2.Call> getCall(UidsQuery query, String lastUpdated) + throws IOException { + return indicatorService.getIndicators( + Indicator.allFields, + Indicator.lastUpdated.gt(lastUpdated), + Indicator.uid.in(query.uids()), + Boolean.FALSE); + } + + public interface Factory { + IndicatorEndpointCall create(GenericCallData data, Set uids); + } + + public static final IndicatorEndpointCall.Factory FACTORY = new IndicatorEndpointCall.Factory() { + @Override + public IndicatorEndpointCall create(GenericCallData data, Set uids) { + return new IndicatorEndpointCall(data, data.retrofit().create(IndicatorService.class), + IndicatorHandler.create(data.databaseAdapter()), UidsQuery.create(uids, null)); + } + }; +} \ No newline at end of file diff --git a/core/src/main/java/org/hisp/dhis/android/core/indicator/IndicatorHandler.java b/core/src/main/java/org/hisp/dhis/android/core/indicator/IndicatorHandler.java new file mode 100644 index 0000000000..d4c1e3d66a --- /dev/null +++ b/core/src/main/java/org/hisp/dhis/android/core/indicator/IndicatorHandler.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2017, University of Oslo + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.hisp.dhis.android.core.indicator; + +import org.hisp.dhis.android.core.common.IdentifiableHandlerImpl; +import org.hisp.dhis.android.core.common.IdentifiableObjectStore; +import org.hisp.dhis.android.core.data.database.DatabaseAdapter; + +public final class IndicatorHandler extends IdentifiableHandlerImpl { + + IndicatorHandler(IdentifiableObjectStore indicatorStore) { + super(indicatorStore); + } + + @Override + protected IndicatorModel pojoToModel(Indicator indicator) { + return IndicatorModel.factory.fromPojo(indicator); + } + + public static IndicatorHandler create(DatabaseAdapter databaseAdapter) { + return new IndicatorHandler(IndicatorStore.create(databaseAdapter)); + } +} diff --git a/core/src/main/java/org/hisp/dhis/android/core/indicator/IndicatorModel.java b/core/src/main/java/org/hisp/dhis/android/core/indicator/IndicatorModel.java new file mode 100644 index 0000000000..b0b1953d25 --- /dev/null +++ b/core/src/main/java/org/hisp/dhis/android/core/indicator/IndicatorModel.java @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2017, University of Oslo + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.hisp.dhis.android.core.indicator; + +import android.database.Cursor; +import android.database.sqlite.SQLiteStatement; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import com.gabrielittner.auto.value.cursor.ColumnName; +import com.google.auto.value.AutoValue; + +import org.hisp.dhis.android.core.common.BaseNameableObjectModel; +import org.hisp.dhis.android.core.common.ModelFactory; +import org.hisp.dhis.android.core.common.StatementBinder; +import org.hisp.dhis.android.core.utils.Utils; + +import static org.hisp.dhis.android.core.utils.StoreUtils.sqLiteBind; + +@AutoValue +public abstract class IndicatorModel extends BaseNameableObjectModel implements StatementBinder { + + public static final String TABLE = "Indicator"; + + public abstract static class Columns extends BaseNameableObjectModel.Columns { + public final static String ANNUALIZED = "annualized"; + public final static String INDICATOR_TYPE = "indicatorType"; + public final static String NUMERATOR = "numerator"; + public final static String NUMERATOR_DESCRIPTION = "numeratorDescription"; + public final static String DENOMINATOR = "denominator"; + public final static String DENOMINATOR_DESCRIPTION = "denominatorDescription"; + public final static String URL = "url"; + + public static String[] all() { + return Utils.appendInNewArray(BaseNameableObjectModel.Columns.all(), + ANNUALIZED, INDICATOR_TYPE, NUMERATOR, NUMERATOR_DESCRIPTION, + DENOMINATOR, DENOMINATOR_DESCRIPTION, URL); + } + } + + static IndicatorModel create(Cursor cursor) { + return AutoValue_IndicatorModel.createFromCursor(cursor); + } + + public static final ModelFactory factory + = new ModelFactory() { + @Override + public IndicatorModel fromCursor(Cursor cursor) { + return create(cursor); + } + + @Override + public IndicatorModel fromPojo(Indicator indicator) { + return IndicatorModel.builder() + .uid(indicator.uid()) + .code(indicator.code()) + .name(indicator.name()) + .displayName(indicator.displayName()) + .created(indicator.created()) + .lastUpdated(indicator.lastUpdated()) + .shortName(indicator.shortName()) + .displayShortName(indicator.displayShortName()) + .description(indicator.description()) + .displayDescription(indicator.displayDescription()) + .annualized(indicator.annualized()) + .indicatorType(indicator.indicatorTypeUid()) + .numerator(indicator.numerator()) + .numeratorDescription(indicator.numeratorDescription()) + .denominator(indicator.denominator()) + .denominatorDescription(indicator.denominatorDescription()) + .url(indicator.url()) + .build(); + } + }; + + public static Builder builder() { + return new $AutoValue_IndicatorModel.Builder(); + } + + @Nullable + @ColumnName(Columns.ANNUALIZED) + public abstract Boolean annualized(); + + @Nullable + @ColumnName(Columns.INDICATOR_TYPE) + public abstract String indicatorType(); + + @Nullable + @ColumnName(Columns.NUMERATOR) + public abstract String numerator(); + + @Nullable + @ColumnName(Columns.NUMERATOR_DESCRIPTION) + public abstract String numeratorDescription(); + + @Nullable + @ColumnName(Columns.DENOMINATOR) + public abstract String denominator(); + + @Nullable + @ColumnName(Columns.DENOMINATOR_DESCRIPTION) + public abstract String denominatorDescription(); + + @Nullable + @ColumnName(Columns.URL) + public abstract String url(); + + @Override + public void bindToStatement(@NonNull SQLiteStatement sqLiteStatement) { + super.bindToStatement(sqLiteStatement); + sqLiteBind(sqLiteStatement, 11, annualized()); + sqLiteBind(sqLiteStatement, 12, indicatorType()); + sqLiteBind(sqLiteStatement, 13, numerator()); + sqLiteBind(sqLiteStatement, 14, numeratorDescription()); + sqLiteBind(sqLiteStatement, 15, denominator()); + sqLiteBind(sqLiteStatement, 16, denominatorDescription()); + sqLiteBind(sqLiteStatement, 17, url()); + } + + @AutoValue.Builder + public static abstract class Builder extends BaseNameableObjectModel.Builder { + public abstract Builder annualized(Boolean annualized); + + public abstract Builder indicatorType(String indicatorType); + + public abstract Builder numerator(String numerator); + + public abstract Builder numeratorDescription(String numeratorDescription); + + public abstract Builder denominator(String denominator); + + public abstract Builder denominatorDescription(String denominatorDescription); + + public abstract Builder url(String url); + + public abstract IndicatorModel build(); + } +} diff --git a/core/src/main/java/org/hisp/dhis/android/core/indicator/IndicatorService.java b/core/src/main/java/org/hisp/dhis/android/core/indicator/IndicatorService.java new file mode 100644 index 0000000000..ea6e90db77 --- /dev/null +++ b/core/src/main/java/org/hisp/dhis/android/core/indicator/IndicatorService.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2017, University of Oslo + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.hisp.dhis.android.core.indicator; + +import org.hisp.dhis.android.core.common.Payload; +import org.hisp.dhis.android.core.data.api.Fields; +import org.hisp.dhis.android.core.data.api.Filter; +import org.hisp.dhis.android.core.data.api.Where; +import org.hisp.dhis.android.core.data.api.Which; + +import retrofit2.Call; +import retrofit2.http.GET; +import retrofit2.http.Query; + +public interface IndicatorService { + @GET("indicators") + Call> getIndicators(@Query("fields") @Which Fields fields, + @Query("filter") @Where Filter lastUpdated, + @Query("filter") @Where Filter uids, + @Query("paging") Boolean paging); + +} diff --git a/core/src/main/java/org/hisp/dhis/android/core/indicator/IndicatorStore.java b/core/src/main/java/org/hisp/dhis/android/core/indicator/IndicatorStore.java new file mode 100644 index 0000000000..35262a84bd --- /dev/null +++ b/core/src/main/java/org/hisp/dhis/android/core/indicator/IndicatorStore.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2017, University of Oslo + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.hisp.dhis.android.core.indicator; + +import org.hisp.dhis.android.core.common.IdentifiableObjectStore; +import org.hisp.dhis.android.core.common.StoreFactory; +import org.hisp.dhis.android.core.data.database.DatabaseAdapter; + +public final class IndicatorStore { + + private IndicatorStore() {} + + public static IdentifiableObjectStore create(DatabaseAdapter databaseAdapter) { + return StoreFactory.identifiableStore(databaseAdapter, IndicatorModel.TABLE, + IndicatorModel.Columns.all()); + } +} \ No newline at end of file diff --git a/core/src/main/java/org/hisp/dhis/android/core/indicator/IndicatorType.java b/core/src/main/java/org/hisp/dhis/android/core/indicator/IndicatorType.java new file mode 100644 index 0000000000..ecf1a80ff9 --- /dev/null +++ b/core/src/main/java/org/hisp/dhis/android/core/indicator/IndicatorType.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2017, University of Oslo + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.hisp.dhis.android.core.indicator; + +import android.support.annotation.Nullable; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.auto.value.AutoValue; + +import org.hisp.dhis.android.core.common.BaseIdentifiableObject; +import org.hisp.dhis.android.core.data.api.Field; +import org.hisp.dhis.android.core.data.api.Fields; + +import java.util.Date; + +@AutoValue +public abstract class IndicatorType extends BaseIdentifiableObject { + private final static String NUMBER = "number"; + private final static String FACTOR = "factor"; + + static final Field uid = Field.create(UID); + private static final Field code = Field.create(CODE); + private static final Field name = Field.create(NAME); + private static final Field displayName = Field.create(DISPLAY_NAME); + private static final Field created = Field.create(CREATED); + static final Field lastUpdated = Field.create(LAST_UPDATED); + private static final Field deleted = Field.create(DELETED); + + private static final Field number = Field.create(NUMBER); + private static final Field factor = Field.create(FACTOR); + + static final Fields allFields = Fields.builder().fields( + uid, code, name, displayName, created, lastUpdated, deleted, + number, factor).build(); + + @Nullable + @JsonProperty(NUMBER) + public abstract Boolean number(); + + @Nullable + @JsonProperty(FACTOR) + public abstract Integer factor(); + + @JsonCreator + public static IndicatorType create( + @JsonProperty(UID) String uid, + @JsonProperty(CODE) String code, + @JsonProperty(NAME) String name, + @JsonProperty(DISPLAY_NAME) String displayName, + @JsonProperty(CREATED) Date created, + @JsonProperty(LAST_UPDATED) Date lastUpdated, + @JsonProperty(NUMBER) Boolean number, + @JsonProperty(FACTOR) Integer factor, + @JsonProperty(DELETED) Boolean deleted) { + + return new AutoValue_IndicatorType(uid, code, name, + displayName, created, lastUpdated, deleted, number, factor); + } +} diff --git a/core/src/main/java/org/hisp/dhis/android/core/indicator/IndicatorTypeEndpointCall.java b/core/src/main/java/org/hisp/dhis/android/core/indicator/IndicatorTypeEndpointCall.java new file mode 100644 index 0000000000..a8da6379fb --- /dev/null +++ b/core/src/main/java/org/hisp/dhis/android/core/indicator/IndicatorTypeEndpointCall.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2017, University of Oslo + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.hisp.dhis.android.core.indicator; + +import org.hisp.dhis.android.core.common.GenericCallData; +import org.hisp.dhis.android.core.common.GenericEndpointCallImpl; +import org.hisp.dhis.android.core.common.GenericHandler; +import org.hisp.dhis.android.core.common.Payload; +import org.hisp.dhis.android.core.common.UidsQuery; +import org.hisp.dhis.android.core.resource.ResourceModel; + +import java.io.IOException; +import java.util.Set; + +import retrofit2.Call; + +public final class IndicatorTypeEndpointCall extends GenericEndpointCallImpl { + private final IndicatorTypeService indicatorTypeService; + + private IndicatorTypeEndpointCall(GenericCallData data, IndicatorTypeService indicatorTypeService, + GenericHandler indicatorTypeHandler, UidsQuery query) { + super(data, indicatorTypeHandler, ResourceModel.Type.INDICATOR_TYPE, query); + this.indicatorTypeService = indicatorTypeService; + } + + @Override + protected Call> getCall(UidsQuery query, String lastUpdated) throws IOException { + return indicatorTypeService.getIndicatorTypes( + IndicatorType.allFields, + IndicatorType.lastUpdated.gt(lastUpdated), + IndicatorType.uid.in(query.uids()), + Boolean.FALSE); + } + + public interface Factory { + IndicatorTypeEndpointCall create(GenericCallData data, Set uids); + } + + public static final IndicatorTypeEndpointCall.Factory FACTORY = new IndicatorTypeEndpointCall.Factory() { + @Override + public IndicatorTypeEndpointCall create(GenericCallData data, Set uids) { + return new IndicatorTypeEndpointCall(data, data.retrofit().create(IndicatorTypeService.class), + IndicatorTypeHandler.create(data.databaseAdapter()), UidsQuery.create(uids, null)); + } + }; +} \ No newline at end of file diff --git a/core/src/main/java/org/hisp/dhis/android/core/indicator/IndicatorTypeHandler.java b/core/src/main/java/org/hisp/dhis/android/core/indicator/IndicatorTypeHandler.java new file mode 100644 index 0000000000..b8ce3a1a91 --- /dev/null +++ b/core/src/main/java/org/hisp/dhis/android/core/indicator/IndicatorTypeHandler.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2017, University of Oslo + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.hisp.dhis.android.core.indicator; + +import org.hisp.dhis.android.core.common.IdentifiableHandlerImpl; +import org.hisp.dhis.android.core.common.IdentifiableObjectStore; +import org.hisp.dhis.android.core.data.database.DatabaseAdapter; + +public class IndicatorTypeHandler extends IdentifiableHandlerImpl { + + IndicatorTypeHandler(IdentifiableObjectStore indicatorTypeStore) { + super(indicatorTypeStore); + } + + @Override + protected IndicatorTypeModel pojoToModel(IndicatorType type) { + return IndicatorTypeModel.factory.fromPojo(type); + } + + public static IndicatorTypeHandler create(DatabaseAdapter databaseAdapter) { + return new IndicatorTypeHandler(IndicatorTypeStore.create(databaseAdapter)); + } +} diff --git a/core/src/main/java/org/hisp/dhis/android/core/indicator/IndicatorTypeModel.java b/core/src/main/java/org/hisp/dhis/android/core/indicator/IndicatorTypeModel.java new file mode 100644 index 0000000000..cc12c1886a --- /dev/null +++ b/core/src/main/java/org/hisp/dhis/android/core/indicator/IndicatorTypeModel.java @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2017, University of Oslo + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.hisp.dhis.android.core.indicator; + +import android.database.Cursor; +import android.database.sqlite.SQLiteStatement; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import com.gabrielittner.auto.value.cursor.ColumnName; +import com.google.auto.value.AutoValue; + +import org.hisp.dhis.android.core.common.BaseIdentifiableObjectModel; +import org.hisp.dhis.android.core.common.BaseNameableObjectModel; +import org.hisp.dhis.android.core.common.ModelFactory; +import org.hisp.dhis.android.core.common.StatementBinder; +import org.hisp.dhis.android.core.utils.Utils; + +import static org.hisp.dhis.android.core.utils.StoreUtils.sqLiteBind; + +@AutoValue +public abstract class IndicatorTypeModel extends BaseIdentifiableObjectModel implements StatementBinder { + + public static final String TABLE = "IndicatorType"; + + public abstract static class Columns extends BaseNameableObjectModel.Columns { + public final static String NUMBER = "number"; + public final static String FACTOR = "factor"; + + public static String[] all() { + return Utils.appendInNewArray(BaseIdentifiableObjectModel.Columns.all(), + NUMBER, FACTOR); + } + } + + static IndicatorTypeModel create(Cursor cursor) { + return AutoValue_IndicatorTypeModel.createFromCursor(cursor); + } + + public static final ModelFactory factory + = new ModelFactory() { + @Override + public IndicatorTypeModel fromCursor(Cursor cursor) { + return create(cursor); + } + + @Override + public IndicatorTypeModel fromPojo(IndicatorType type) { + return IndicatorTypeModel.builder() + .uid(type.uid()) + .code(type.code()) + .name(type.name()) + .displayName(type.displayName()) + .created(type.created()) + .lastUpdated(type.lastUpdated()) + .number(type.number()) + .factor(type.factor()) + .build(); + } + }; + + public static Builder builder() { + return new $AutoValue_IndicatorTypeModel.Builder(); + } + + @Nullable + @ColumnName(Columns.NUMBER) + public abstract Boolean number(); + + @Nullable + @ColumnName(Columns.FACTOR) + public abstract Integer factor(); + + @Override + public void bindToStatement(@NonNull SQLiteStatement sqLiteStatement) { + super.bindToStatement(sqLiteStatement); + sqLiteBind(sqLiteStatement, 7, number()); + sqLiteBind(sqLiteStatement, 8, factor()); + } + + @AutoValue.Builder + public static abstract class Builder extends BaseIdentifiableObjectModel.Builder { + public abstract Builder number(Boolean number); + + public abstract Builder factor(Integer factor); + + public abstract IndicatorTypeModel build(); + } +} diff --git a/core/src/main/java/org/hisp/dhis/android/core/indicator/IndicatorTypeService.java b/core/src/main/java/org/hisp/dhis/android/core/indicator/IndicatorTypeService.java new file mode 100644 index 0000000000..a8888a7416 --- /dev/null +++ b/core/src/main/java/org/hisp/dhis/android/core/indicator/IndicatorTypeService.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2017, University of Oslo + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.hisp.dhis.android.core.indicator; + +import org.hisp.dhis.android.core.common.Payload; +import org.hisp.dhis.android.core.data.api.Fields; +import org.hisp.dhis.android.core.data.api.Filter; +import org.hisp.dhis.android.core.data.api.Where; +import org.hisp.dhis.android.core.data.api.Which; + +import retrofit2.Call; +import retrofit2.http.GET; +import retrofit2.http.Query; + +public interface IndicatorTypeService { + @GET("indicatorTypes") + Call> getIndicatorTypes(@Query("fields") @Which Fields fields, + @Query("filter") @Where Filter lastUpdated, + @Query("filter") @Where Filter uids, + @Query("paging") Boolean paging); + +} diff --git a/core/src/main/java/org/hisp/dhis/android/core/indicator/IndicatorTypeStore.java b/core/src/main/java/org/hisp/dhis/android/core/indicator/IndicatorTypeStore.java new file mode 100644 index 0000000000..83f50d84c8 --- /dev/null +++ b/core/src/main/java/org/hisp/dhis/android/core/indicator/IndicatorTypeStore.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2017, University of Oslo + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.hisp.dhis.android.core.indicator; + +import org.hisp.dhis.android.core.common.IdentifiableObjectStore; +import org.hisp.dhis.android.core.common.StoreFactory; +import org.hisp.dhis.android.core.data.database.DatabaseAdapter; + +public final class IndicatorTypeStore { + + private IndicatorTypeStore() {} + + public static IdentifiableObjectStore create(DatabaseAdapter databaseAdapter) { + return StoreFactory.identifiableStore(databaseAdapter, IndicatorTypeModel.TABLE, + IndicatorTypeModel.Columns.all()); + } +} \ No newline at end of file diff --git a/core/src/main/java/org/hisp/dhis/android/core/option/Option.java b/core/src/main/java/org/hisp/dhis/android/core/option/Option.java index 7f87004f5a..6412e09139 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/option/Option.java +++ b/core/src/main/java/org/hisp/dhis/android/core/option/Option.java @@ -35,6 +35,7 @@ import com.google.auto.value.AutoValue; import org.hisp.dhis.android.core.common.BaseIdentifiableObject; +import org.hisp.dhis.android.core.common.ObjectStyle; import org.hisp.dhis.android.core.data.api.Field; import org.hisp.dhis.android.core.data.api.NestedField; @@ -43,6 +44,7 @@ @AutoValue public abstract class Option extends BaseIdentifiableObject { private static final String OPTION_SET = "optionSet"; + private final static String STYLE = "style"; public static final Field uid = Field.create(UID); public static final Field code = Field.create(CODE); @@ -52,11 +54,16 @@ public abstract class Option extends BaseIdentifiableObject { public static final Field lastUpdated = Field.create(LAST_UPDATED); public static final Field deleted = Field.create(DELETED); public static final NestedField optionSet = NestedField.create(OPTION_SET); + public static final NestedField style = NestedField.create(STYLE); @Nullable @JsonProperty(OPTION_SET) public abstract OptionSet optionSet(); + @Nullable + @JsonProperty(STYLE) + public abstract ObjectStyle style(); + @JsonCreator public static Option create( @JsonProperty(UID) String uid, @@ -66,8 +73,9 @@ public static Option create( @JsonProperty(CREATED) Date created, @JsonProperty(LAST_UPDATED) Date lastUpdated, @JsonProperty(OPTION_SET) OptionSet optionSet, + @JsonProperty(STYLE) ObjectStyle style, @JsonProperty(DELETED) Boolean deleted) { - return new AutoValue_Option(uid, code, name, displayName, created, lastUpdated, deleted, optionSet); + return new AutoValue_Option(uid, code, name, displayName, created, lastUpdated, deleted, optionSet, style); } } diff --git a/core/src/main/java/org/hisp/dhis/android/core/option/OptionHandler.java b/core/src/main/java/org/hisp/dhis/android/core/option/OptionHandler.java index 1c8495aa70..feb465cca8 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/option/OptionHandler.java +++ b/core/src/main/java/org/hisp/dhis/android/core/option/OptionHandler.java @@ -27,15 +27,21 @@ */ package org.hisp.dhis.android.core.option; +import org.hisp.dhis.android.core.common.DictionaryTableHandler; +import org.hisp.dhis.android.core.common.ObjectStyle; + import java.util.List; import static org.hisp.dhis.android.core.utils.Utils.isDeleted; public class OptionHandler { private final OptionStore optionStore; + private final DictionaryTableHandler styleHandler; + - public OptionHandler(OptionStore optionStore) { + public OptionHandler(OptionStore optionStore, DictionaryTableHandler styleHandler) { this.optionStore = optionStore; + this.styleHandler = styleHandler; } public void handleOptions(List