package de.westnordost.streetcomplete.data.statistics; import android.content.ContentValues; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import java.util.HashMap; import java.util.Map; import javax.inject.Inject; import de.westnordost.osmapi.map.changes.MapDataChangesHandler; import de.westnordost.osmapi.map.data.BoundingBox; import de.westnordost.osmapi.map.data.Node; import de.westnordost.osmapi.map.data.Relation; import de.westnordost.osmapi.map.data.Way; import de.westnordost.streetcomplete.ApplicationConstants; import de.westnordost.osmapi.changesets.ChangesetInfo; import de.westnordost.osmapi.changesets.ChangesetsDao; import de.westnordost.osmapi.common.Handler; public class QuestStatisticsDao { private final SQLiteOpenHelper dbHelper; private final ChangesetsDao changesetsDao; private final UserChangesetsDao userChangesetsDao; @Inject public QuestStatisticsDao(SQLiteOpenHelper dbHelper, ChangesetsDao changesetsDao) { this.dbHelper = dbHelper; this.changesetsDao = changesetsDao; this.userChangesetsDao = new UserChangesetsDao(changesetsDao); } public void syncFromOsmServer(long userId) { final Map<String, Integer> data = new HashMap<>(); userChangesetsDao.findAll(new Handler<ChangesetInfo>() { @Override public void handle(ChangesetInfo changeset) { if(changeset.tags == null) return; String userAgent = changeset.tags.get("created_by"); if(userAgent == null) return; if(!userAgent.startsWith(ApplicationConstants.NAME)) return; String questType = changeset.tags.get(ApplicationConstants.QUESTTYPE_TAG_KEY); if(questType == null) return; int prev = data.get(questType) != null ? data.get(questType) : 0; MapDataChangesCounter counter = new MapDataChangesCounter(); changesetsDao.getData(changeset.id, counter); data.put(questType, prev + counter.count ); } }, userId, ApplicationConstants.DATE_OF_BIRTH); SQLiteDatabase db = dbHelper.getWritableDatabase(); // clear table db.delete(QuestStatisticsTable.NAME, null, null); for(Map.Entry<String, Integer> dataForQuestType : data.entrySet()) { ContentValues values = new ContentValues(2); values.put(QuestStatisticsTable.Columns.QUEST_TYPE, dataForQuestType.getKey()); values.put(QuestStatisticsTable.Columns.SUCCEEDED, dataForQuestType.getValue()); db.insert(QuestStatisticsTable.NAME, null, values); } } private static class MapDataChangesCounter implements MapDataChangesHandler { int count = 0; @Override public void onStartCreations() {} @Override public void onStartModifications() {} @Override public void onStartDeletions() {} @Override public void handle(BoundingBox bounds) {} @Override public void handle(Node node) { count++; } @Override public void handle(Way way) { count++; } @Override public void handle(Relation relation) { count++; } } public void addOne(String questType) { SQLiteDatabase db = dbHelper.getWritableDatabase(); // first ensure the row exists ContentValues values = new ContentValues(); values.put(QuestStatisticsTable.Columns.QUEST_TYPE, questType); values.put(QuestStatisticsTable.Columns.SUCCEEDED, 0); db.insertWithOnConflict(QuestStatisticsTable.NAME, null, values, SQLiteDatabase.CONFLICT_IGNORE); // then increase by one String[] args = {questType}; db.execSQL("UPDATE " + QuestStatisticsTable.NAME + " SET " + QuestStatisticsTable.Columns.SUCCEEDED + " = " + QuestStatisticsTable.Columns.SUCCEEDED + " + 1 WHERE " + QuestStatisticsTable.Columns.QUEST_TYPE + " = ?", args); } public int getAmount(String questType) { SQLiteDatabase db = dbHelper.getReadableDatabase(); Cursor cursor = db.query(QuestStatisticsTable.NAME, new String[]{QuestStatisticsTable.Columns.SUCCEEDED}, QuestStatisticsTable.Columns.QUEST_TYPE + " = ?", new String[]{questType}, null, null, null, "1"); try { if(!cursor.moveToFirst()) return 0; return cursor.getInt(0); } finally { cursor.close(); } } public int getTotalAmount() { SQLiteDatabase db = dbHelper.getReadableDatabase(); String[] cols = {"total("+QuestStatisticsTable.Columns.SUCCEEDED+")"}; Cursor cursor = db.query(QuestStatisticsTable.NAME, cols, null, null, null, null, null, null); try { if(!cursor.moveToFirst()) return 0; return cursor.getInt(0); } finally { cursor.close(); } } }