package com.rapidftr.repository; import android.content.ContentValues; import android.database.Cursor; import android.util.Log; import com.google.inject.Inject; import com.google.inject.name.Named; import com.rapidftr.RapidFtrApplication; import com.rapidftr.adapter.pagination.ViewAllChildrenPaginatedScrollListener; import com.rapidftr.database.Database; import com.rapidftr.database.DatabaseSession; import com.rapidftr.model.Child; import com.rapidftr.model.Enquiry; import com.rapidftr.model.History; import com.rapidftr.model.User; import com.rapidftr.utils.RapidFtrDateTime; import lombok.Cleanup; import org.json.JSONException; import java.io.Closeable; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import static com.rapidftr.database.Database.BooleanColumn.falseValue; import static com.rapidftr.database.Database.EnquiryTableColumn.*; import static com.rapidftr.database.Database.enquiry; public class EnquiryRepository implements Closeable, Repository<Enquiry> { private final String userName; private final DatabaseSession session; private final RapidFtrApplication applicationInstance; @Inject public EnquiryRepository(@Named("USER_NAME") String userName, DatabaseSession session, RapidFtrApplication rapidFtrApplication) { this.userName = userName; this.session = session; this.applicationInstance = rapidFtrApplication; } @Override public void createOrUpdate(Enquiry enquiry) throws JSONException { if (exists(enquiry.getUniqueId())) { Enquiry existingEnquiry = get(enquiry.getUniqueId()); enquiry.addHistory(History.buildHistoryBetween(applicationInstance, existingEnquiry, enquiry)); } else { User currentUser = RapidFtrApplication.getApplicationInstance().getCurrentUser(); enquiry.addHistory(History.buildCreationHistory(enquiry, currentUser)); } enquiry.setLastUpdatedAt(RapidFtrDateTime.now().defaultFormat()); createOrUpdateWithoutHistory(enquiry); } @Override public void createOrUpdateWithoutHistory(Enquiry enquiry) throws JSONException { session.replaceOrThrow(Database.enquiry.getTableName(), null, getContentValuesFrom(enquiry)); } protected ContentValues getContentValuesFrom(Enquiry enquiry) throws JSONException { ContentValues enquiryValues = new ContentValues(); enquiryValues.put(id.getColumnName(), enquiry.getUniqueId()); enquiryValues.put(created_by.getColumnName(), enquiry.getCreatedBy()); enquiryValues.put(content.getColumnName(), enquiry.getJsonString()); enquiryValues.put(created_at.getColumnName(), enquiry.getCreatedAt()); enquiryValues.put(unique_identifier.getColumnName(), enquiry.getUniqueId()); enquiryValues.put(synced.getColumnName(), enquiry.isSynced()); enquiryValues.put(internal_id.getColumnName(), enquiry.optString(internal_id.getColumnName())); enquiryValues.put(internal_rev.getColumnName(), enquiry.optString(internal_rev.getColumnName())); return enquiryValues; } @Override public HashMap<String, String> getAllIdsAndRevs() throws JSONException { HashMap<String, String> idRevs = new HashMap<String, String>(); @Cleanup Cursor cursor = session.rawQuery("SELECT " + internal_id.getColumnName() + ", " + internal_rev.getColumnName() + " FROM " + enquiry.getTableName(), null); while (cursor.moveToNext()) { idRevs.put(cursor.getString(0), cursor.getString(1)); } return idRevs; } public List<Enquiry> allCreatedByCurrentUser() throws JSONException { @Cleanup Cursor cursor = session.rawQuery("SELECT enquiry_json FROM enquiry WHERE created_by = ? ORDER BY id", new String[]{userName}); return toEnquiries(cursor); } @Override public List<Enquiry> currentUsersUnsyncedRecords() throws JSONException { throw new UnsupportedOperationException(); } @Override public List<String> getRecordIdsByOwner() throws JSONException { throw new UnsupportedOperationException(); } @Override public List<Enquiry> toBeSynced() throws JSONException { @Cleanup Cursor cursor = session.rawQuery("SELECT * FROM enquiry WHERE synced" + " = ?", new String[]{falseValue.getColumnValue()}); return toEnquiries(cursor); } @Override public boolean exists(String id) { @Cleanup Cursor cursor = session.rawQuery("SELECT * FROM enquiry WHERE id = ?", new String[]{id == null ? "" : id}); return cursor.moveToNext() && cursor.getCount() > 0; } @Override public int size() { @Cleanup Cursor cursor = session.rawQuery("SELECT COUNT(1) FROM enquiry", new String[]{}); return cursor.moveToNext() ? cursor.getInt(0) : 0; } @Override public void close() { try { session.close(); } catch (IOException e) { throw new RuntimeException(e); } } public List<Enquiry> all() throws JSONException { @Cleanup Cursor cursor = session.rawQuery("SELECT * FROM enquiry", new String[]{}); return toEnquiries(cursor); } List<Enquiry> toEnquiries(Cursor cursor) throws JSONException { List<Enquiry> enquiries = new ArrayList<Enquiry>(); while (cursor.moveToNext()) { enquiries.add(buildEnquiry(cursor)); } return enquiries; } //TODO move this to the enquiry class private Enquiry buildEnquiry(Cursor cursor) throws JSONException { int contentColumnIndex = cursor.getColumnIndex(content.getColumnName()); Enquiry enquiry = new Enquiry(cursor.getString(contentColumnIndex)); for (Database.EnquiryTableColumn column : Database.EnquiryTableColumn.values()) { final int columnIndex = cursor.getColumnIndex(column.getColumnName()); if (columnIndex < 0 || column.equals(content)) { continue; } else if (column.getPrimitiveType().equals(Boolean.class)) { enquiry.put(column.getColumnName(), cursor.getInt(columnIndex) == 1); } else { enquiry.put(column.getColumnName(), cursor.getString(columnIndex)); } } return enquiry; } public Enquiry get(String enquiryId) throws JSONException { @Cleanup Cursor cursor = session.rawQuery("SELECT * from enquiry where id = ?", new String[]{enquiryId}); if (cursor.moveToNext()) { return new Enquiry(cursor); } else { throw new NullPointerException(enquiryId); // I don't think it's cool to throw NullPointerExceptions - love John } } public List<Enquiry> getAllWithInternalIds(List<String> ids) { @Cleanup Cursor cursor = session.rawQuery(buildSelectAllQuery(ids), null); try { return toEnquiries(cursor); } catch (JSONException e) { return new ArrayList<Enquiry>(); } } @Override public List<Enquiry> getRecordsForFirstPage() throws JSONException { String sql = String.format( "SELECT enquiry_json, synced FROM enquiry WHERE created_by ='%s' ORDER BY id LIMIT %d", userName, ViewAllChildrenPaginatedScrollListener.FIRST_PAGE); @Cleanup Cursor cursor = session.rawQuery(sql, null); return toEnquiries(cursor); } @Override public List<Enquiry> getRecordsBetween(int fromPageNumber, int pageNumber) throws JSONException { String sql = String.format( "SELECT enquiry_json, synced FROM enquiry WHERE created_by='%s' ORDER BY id LIMIT %d OFFSET %d", userName, pageNumber - fromPageNumber, pageNumber); Log.d("QUERY LIMIT", sql); @Cleanup Cursor cursor = session.rawQuery(sql, null); return toEnquiries(cursor); } private String buildSelectAllQuery(List<String> ids) { StringBuilder queryBuilder = new StringBuilder(); queryBuilder.append("SELECT * from enquiry where _id in ("); for(int i = 0; i < ids.size(); i++) { queryBuilder.append("'" + ids.get(i) + "'"); if(i < ids.size() - 1) { queryBuilder.append(","); } } queryBuilder.append(")"); return queryBuilder.toString(); } }