/* * The contents of this file are subject to the OpenMRS Public License * Version 1.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://license.openmrs.org * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the * License for the specific language governing rights and limitations * under the License. * * Copyright (C) OpenMRS, LLC. All Rights Reserved. */ package org.openmrs.mobile.databases; import android.content.ContentValues; import android.content.Context; import android.graphics.Bitmap; import net.sqlcipher.database.SQLiteDatabase; import net.sqlcipher.database.SQLiteStatement; import org.openmrs.mobile.R; import org.openmrs.mobile.application.OpenMRS; import org.openmrs.mobile.databases.tables.ConceptTable; import org.openmrs.mobile.databases.tables.EncounterTable; import org.openmrs.mobile.databases.tables.LocationTable; import org.openmrs.mobile.databases.tables.ObservationTable; import org.openmrs.mobile.databases.tables.PatientTable; import org.openmrs.mobile.databases.tables.Table; import org.openmrs.mobile.databases.tables.VisitTable; import org.openmrs.mobile.models.Concept; import org.openmrs.mobile.models.Encounter; import org.openmrs.mobile.models.Location; import org.openmrs.mobile.models.Observation; import org.openmrs.mobile.models.Patient; import org.openmrs.mobile.models.Visit; import java.io.ByteArrayOutputStream; import java.util.concurrent.Callable; import rx.Observable; import rx.schedulers.Schedulers; public class DBOpenHelper extends OpenMRSSQLiteOpenHelper { private static int DATABASE_VERSION = OpenMRS.getInstance(). getResources().getInteger(R.integer.dbversion); private static final String WHERE_ID_CLAUSE = String.format("%s = ?", Table.MasterColumn.ID); private PatientTable mPatientTable; private ConceptTable mConceptTable; private VisitTable mVisitTable; private EncounterTable mEncounterTable; private ObservationTable mObservationTable; private LocationTable mLocationTable; public DBOpenHelper(Context context) { super(context, null, DATABASE_VERSION); this.mPatientTable = new PatientTable(); this.mConceptTable = new ConceptTable(); this.mVisitTable = new VisitTable(); this.mEncounterTable = new EncounterTable(); this.mObservationTable = new ObservationTable(); this.mLocationTable = new LocationTable(); } @Override public void onCreate(SQLiteDatabase sqLiteDatabase) { mLogger.d("Database creating..."); sqLiteDatabase.execSQL(mPatientTable.createTableDefinition()); logOnCreate(mPatientTable.toString()); sqLiteDatabase.execSQL(mConceptTable.createTableDefinition()); logOnCreate(mConceptTable.toString()); sqLiteDatabase.execSQL(mVisitTable.createTableDefinition()); logOnCreate(mVisitTable.toString()); sqLiteDatabase.execSQL(mEncounterTable.createTableDefinition()); logOnCreate(mEncounterTable.toString()); sqLiteDatabase.execSQL(mObservationTable.createTableDefinition()); logOnCreate(mObservationTable.toString()); sqLiteDatabase.execSQL(mLocationTable.createTableDefinition()); logOnCreate(mLocationTable.toString()); } @Override public void onUpgrade(SQLiteDatabase sqLiteDatabase, int currentVersion, int newVersion) { switch (currentVersion) { case 8: sqLiteDatabase.execSQL(new ConceptTable().createTableDefinition()); case 9: //upgrade from version 8 to 10 //db.execSQL("ALTER TABLE " + %tableName% + " ADD COLUMN " + %columnName + " %columnType%;"); //and so on.. do not add breaks so that switch will //start at oldVersion, and run straight through to the latest } } private void logOnCreate(String tableToString) { mLogger.d("Table " + tableToString + " ver." + DATABASE_VERSION + " created"); } public long insertPatient(SQLiteDatabase db, Patient patient) { long patientId; SQLiteStatement patientStatement = db.compileStatement(mPatientTable.insertIntoTableDefinition()); try { db.beginTransaction(); bindString(1, patient.getPerson().getName().getNameString(), patientStatement); bindString(2, Boolean.toString(patient.isSynced()),patientStatement); if(patient.getUuid()!=null) bindString(3, patient.getUuid(), patientStatement); else bindString(3, null, patientStatement); if(patient.getIdentifier()!=null) bindString(4, patient.getIdentifier().getIdentifier(), patientStatement); else bindString(4, null, patientStatement); bindString(5, patient.getPerson().getName().getGivenName(), patientStatement); bindString(6, patient.getPerson().getName().getMiddleName(), patientStatement); bindString(7, patient.getPerson().getName().getFamilyName(), patientStatement); bindString(8, patient.getPerson().getGender(), patientStatement); bindString(9, patient.getPerson().getBirthdate(), patientStatement); bindLong(10, null, patientStatement); bindString(11, null, patientStatement); bindString(12, null, patientStatement); if (null != patient.getPerson().getPhoto()) { bindBlob(13, bitmapToByteArray(patient.getPerson().getPhoto()), patientStatement); } if (null != patient.getPerson().getAddress()) { bindString(14, patient.getPerson().getAddress().getAddress1(), patientStatement); bindString(15, patient.getPerson().getAddress().getAddress2(), patientStatement); bindString(16, patient.getPerson().getAddress().getPostalCode(), patientStatement); bindString(17, patient.getPerson().getAddress().getCountry(), patientStatement); bindString(18, patient.getPerson().getAddress().getStateProvince(), patientStatement); bindString(19, patient.getPerson().getAddress().getCityVillage(), patientStatement); } bindString(20, patient.getEncounters(), patientStatement); bindString(21, null, patientStatement); patientId = patientStatement.executeInsert(); patientStatement.clearBindings(); db.setTransactionSuccessful(); } finally { db.endTransaction(); patientStatement.close(); } patient.setId(patientId); return patientId; } public int updatePatient(SQLiteDatabase db, long patientID, Patient patient) { ContentValues newValues = new ContentValues(); newValues.put(PatientTable.Column.UUID, patient.getUuid()); newValues.put(PatientTable.Column.SYNCED, patient.isSynced()); newValues.put(PatientTable.Column.DISPLAY, patient.getDisplay()); newValues.put(PatientTable.Column.IDENTIFIER, patient.getIdentifier().getIdentifier()); newValues.put(PatientTable.Column.GIVEN_NAME, patient.getPerson().getName().getGivenName()); newValues.put(PatientTable.Column.MIDDLE_NAME, patient.getPerson().getName().getMiddleName()); newValues.put(PatientTable.Column.FAMILY_NAME, patient.getPerson().getName().getFamilyName()); newValues.put(PatientTable.Column.GENDER, patient.getPerson().getGender()); newValues.put(PatientTable.Column.BIRTH_DATE, patient.getPerson().getBirthdate()); newValues.put(PatientTable.Column.DEATH_DATE, (Long) null); newValues.put(PatientTable.Column.CAUSE_OF_DEATH, (String) null); newValues.put(PatientTable.Column.AGE, (String) null); if (null != patient.getPerson().getPhoto()) { mLogger.i("inserting into db"); newValues.put(PatientTable.Column.PHOTO, bitmapToByteArray(patient.getPerson().getPhoto())); } if (null != patient.getPerson().getAddress()) { newValues.put(PatientTable.Column.ADDRESS_1, patient.getPerson().getAddress().getAddress1()); newValues.put(PatientTable.Column.ADDRESS_2, patient.getPerson().getAddress().getAddress2()); newValues.put(PatientTable.Column.POSTAL_CODE, patient.getPerson().getAddress().getPostalCode()); newValues.put(PatientTable.Column.COUNTRY, patient.getPerson().getAddress().getCountry()); newValues.put(PatientTable.Column.STATE, patient.getPerson().getAddress().getStateProvince()); newValues.put(PatientTable.Column.CITY, patient.getPerson().getAddress().getCityVillage()); } newValues.put(PatientTable.Column.ENCOUNTERS, patient.getEncounters()); String[] whereArgs = new String[]{String.valueOf(patientID)}; return db.update(PatientTable.TABLE_NAME, newValues, WHERE_ID_CLAUSE, whereArgs); } public long insertConcept (SQLiteDatabase db, Concept concept) { long conceptId; SQLiteStatement statement = db.compileStatement(mConceptTable.insertIntoTableDefinition()); try { db.beginTransaction(); bindString(1, concept.getUuid(), statement); bindString(2, concept.getDisplay(), statement); conceptId = statement.executeInsert(); statement.clearBindings(); db.setTransactionSuccessful(); } finally { db.endTransaction(); statement.close(); } return conceptId; } public int updateConcept (SQLiteDatabase db, long conceptId, Concept concept) { ContentValues newValues = new ContentValues(); newValues.put(ConceptTable.Column.UUID, concept.getUuid()); newValues.put(ConceptTable.Column.DISPLAY, concept.getDisplay()); String[] whereArgs = new String[]{String.valueOf(conceptId)}; return db.update(ConceptTable.TABLE_NAME, newValues, WHERE_ID_CLAUSE, whereArgs); } public long insertVisit(SQLiteDatabase db, Visit visit) { long visitId; SQLiteStatement visitStatement = db.compileStatement(mVisitTable.insertIntoTableDefinition()); try { db.beginTransaction(); bindString(1, visit.getUuid(), visitStatement); bindLong(2, visit.getPatient().getId(), visitStatement); bindString(3, visit.getVisitType().getDisplay(), visitStatement); if (visit.getLocation() != null) { bindString(4, visit.getLocation().getDisplay(), visitStatement); } bindString(5, visit.getStartDatetime(), visitStatement); bindString(6, visit.getStopDatetime(), visitStatement); visitId = visitStatement.executeInsert(); visitStatement.clearBindings(); db.setTransactionSuccessful(); } finally { db.endTransaction(); visitStatement.close(); } return visitId; } public int updateVisit(SQLiteDatabase db, long visitID, Visit visit) { ContentValues newValues = new ContentValues(); newValues.put(VisitTable.Column.UUID, visit.getUuid()); newValues.put(VisitTable.Column.PATIENT_KEY_ID, visit.getPatient().getId()); newValues.put(VisitTable.Column.VISIT_TYPE, visit.getVisitType().getDisplay()); if (visit.getLocation() != null) { newValues.put(VisitTable.Column.VISIT_PLACE, visit.getLocation().getDisplay()); } newValues.put(VisitTable.Column.START_DATE, visit.getStartDatetime()); newValues.put(VisitTable.Column.STOP_DATE, visit.getStopDatetime()); String[] whereArgs = new String[]{String.valueOf(visitID)}; return db.update(VisitTable.TABLE_NAME, newValues, WHERE_ID_CLAUSE, whereArgs); } public long insertEncounter(SQLiteDatabase db, Encounter encounter) { long encounterId; SQLiteStatement encounterStatement = db.compileStatement(mEncounterTable.insertIntoTableDefinition()); try { db.beginTransaction(); bindLong(1, encounter.getVisitID(), encounterStatement); bindString(2, encounter.getUuid(), encounterStatement); bindString(3, encounter.getDisplay(), encounterStatement); bindLong(4, encounter.getEncounterDatetime(), encounterStatement); bindString(5, encounter.getEncounterType().getDisplay(), encounterStatement); bindString(6, encounter.getPatientUUID(), encounterStatement); bindString(7, encounter.getFormUuid(), encounterStatement); encounterId = encounterStatement.executeInsert(); encounterStatement.clearBindings(); db.setTransactionSuccessful(); } finally { db.endTransaction(); encounterStatement.close(); } return encounterId; } public int updateEncounter(SQLiteDatabase db, long encounterID, Encounter encounter) { ContentValues newValues = new ContentValues(); newValues.put(EncounterTable.Column.UUID, encounter.getUuid()); newValues.put(EncounterTable.Column.VISIT_KEY_ID, encounter.getVisitID()); newValues.put(EncounterTable.Column.DISPLAY, encounter.getDisplay()); newValues.put(EncounterTable.Column.ENCOUNTER_DATETIME, encounter.getEncounterDatetime()); newValues.put(EncounterTable.Column.ENCOUNTER_TYPE, encounter.getEncounterType().getDisplay()); String[] whereArgs = new String[]{String.valueOf(encounterID)}; return db.update(EncounterTable.TABLE_NAME, newValues, WHERE_ID_CLAUSE, whereArgs); } public long insertObservation(SQLiteDatabase db, Observation obs) { long obsID; SQLiteStatement observationStatement = db.compileStatement(mObservationTable.insertIntoTableDefinition()); try { db.beginTransaction(); bindLong(1, obs.getEncounterID(), observationStatement); bindString(2, obs.getUuid(), observationStatement); bindString(3, obs.getDisplay(), observationStatement); bindString(4, obs.getDisplayValue(), observationStatement); if (obs.getDiagnosisOrder() != null) { bindString(5, obs.getDiagnosisOrder(), observationStatement); } bindString(6, obs.getDiagnosisList(), observationStatement); if (obs.getDiagnosisCertainty() != null) { bindString(7, obs.getDiagnosisCertainty(), observationStatement); } bindString(8, obs.getDiagnosisNote(), observationStatement); if(obs.getConcept() != null){ bindString(9, obs.getConcept().getUuid(), observationStatement); } obsID = observationStatement.executeInsert(); observationStatement.clearBindings(); db.setTransactionSuccessful(); } finally { db.endTransaction(); observationStatement.close(); } return obsID; } public int updateObservation(SQLiteDatabase db, long observationID, Observation observation) { ContentValues newValues = new ContentValues(); newValues.put(ObservationTable.Column.UUID, observation.getUuid()); newValues.put(ObservationTable.Column.ENCOUNTER_KEY_ID, observation.getEncounterID()); newValues.put(ObservationTable.Column.DISPLAY, observation.getDisplay()); newValues.put(ObservationTable.Column.DISPLAY_VALUE, observation.getDisplayValue()); if (observation.getDiagnosisOrder() != null) { newValues.put(ObservationTable.Column.DIAGNOSIS_ORDER, observation.getDiagnosisOrder()); } newValues.put(ObservationTable.Column.DIAGNOSIS_LIST, observation.getDiagnosisList()); if (observation.getDiagnosisCertainty() != null) { newValues.put(ObservationTable.Column.DIAGNOSIS_CERTAINTY, observation.getDiagnosisCertainty()); } newValues.put(ObservationTable.Column.DIAGNOSIS_NOTE, observation.getDiagnosisNote()); String[] whereArgs = new String[]{String.valueOf(observationID)}; return db.update(ObservationTable.TABLE_NAME, newValues, WHERE_ID_CLAUSE, whereArgs); } public Long insertLocation(SQLiteDatabase db, Location loc) { long locID; SQLiteStatement locationStatement = db.compileStatement(mLocationTable.insertIntoTableDefinition()); try { db.beginTransaction(); bindString(1, loc.getUuid(), locationStatement); bindString(2, loc.getDisplay(), locationStatement); bindString(3, loc.getName(), locationStatement); bindString(4, loc.getDescription(), locationStatement); bindString(5, loc.getAddress1(), locationStatement); bindString(6, loc.getAddress2(), locationStatement); bindString(7, loc.getCityVillage(), locationStatement); bindString(8, loc.getStateProvince(), locationStatement); bindString(9, loc.getCountry(), locationStatement); bindString(10, loc.getPostalCode(), locationStatement); bindString(11, loc.getParentLocationUuid(), locationStatement); locID = locationStatement.executeInsert(); locationStatement.clearBindings(); db.setTransactionSuccessful(); } finally { db.endTransaction(); locationStatement.close(); } return locID; } public static <T> Observable<T> createObservableIO(final Callable<T> func) { return Observable.fromCallable(func) .subscribeOn(Schedulers.io()); } private byte[] bitmapToByteArray(Bitmap image) { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); image.compress(Bitmap.CompressFormat.PNG, 0, outputStream); return outputStream.toByteArray(); } }