diff --git a/app/src/main/java/com/geeksville/mesh/ui/MapFragment.kt b/app/src/main/java/com/geeksville/mesh/ui/MapFragment.kt index a910cef7..e3d334fb 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/MapFragment.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/MapFragment.kt @@ -22,6 +22,8 @@ import com.geeksville.mesh.databinding.MapViewBinding import com.geeksville.mesh.model.UIViewModel import com.geeksville.mesh.model.map.CustomOverlayManager import com.geeksville.mesh.model.map.CustomTileSource +import com.geeksville.mesh.util.SqlTileWriterExt +import com.geeksville.mesh.util.SqlTileWriterExt.SourceCount import com.geeksville.mesh.util.formatAgo import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.floatingactionbutton.FloatingActionButton @@ -60,6 +62,7 @@ class MapFragment : ScreenFragment("Map"), Logging, View.OnClickListener { private lateinit var executeJob: Button private var downloadPrompt: AlertDialog? = null private var alertDialog: AlertDialog? = null + private var cache: SqlTileWriterExt? = null // constants private val defaultMinZoom = 1.5 @@ -170,7 +173,7 @@ class MapFragment : ScreenFragment("Map"), Logging, View.OnClickListener { downloadJobAlert() dialog.dismiss() } - 2 -> clearCache() + 2 -> purgeTileSource() else -> dialog.dismiss() } } @@ -181,6 +184,7 @@ class MapFragment : ScreenFragment("Map"), Logging, View.OnClickListener { alertDialog!!.show() } + /** * Clears active tile source cache */ @@ -193,6 +197,36 @@ class MapFragment : ScreenFragment("Map"), Logging, View.OnClickListener { alertDialog!!.dismiss() } + private fun purgeTileSource() { + cache = SqlTileWriterExt() + val builder = AlertDialog.Builder(context) + builder.setTitle("Tile Source") + val arrayAdapter: ArrayAdapter = + ArrayAdapter(context!!, android.R.layout.select_dialog_singlechoice) + val sources = cache!!.sources + for (i in sources.indices) { + arrayAdapter.add(sources[i].source) + } + builder.setAdapter(arrayAdapter) { dialog, which -> + val item = arrayAdapter.getItem(which) + val b = cache!!.purgeCache(item) + if (b) Toast.makeText( + context, + "SQL Cache purged", + Toast.LENGTH_SHORT + ) + .show() else Toast.makeText( + context, + "SQL Cache purge failed, see logcat for details", + Toast.LENGTH_LONG + ).show() + } + builder.setNegativeButton( + "Cancel" + ) { dialog, which -> dialog.cancel() } + builder.show() + } + private fun showCurrentCacheInfo() { Toast.makeText(activity, "Calculating...", Toast.LENGTH_SHORT).show() diff --git a/app/src/main/java/com/geeksville/mesh/util/SqlTileWriterExt.kt b/app/src/main/java/com/geeksville/mesh/util/SqlTileWriterExt.kt new file mode 100644 index 00000000..edeea830 --- /dev/null +++ b/app/src/main/java/com/geeksville/mesh/util/SqlTileWriterExt.kt @@ -0,0 +1,81 @@ +package com.geeksville.mesh.util + +import android.database.Cursor +import org.osmdroid.tileprovider.modules.DatabaseFileArchive +import org.osmdroid.tileprovider.modules.SqlTileWriter + + +/** + * Extended the sqlite tile writer to have some additional query functions. A this point + * it's unclear if there is a need to put these with the osmdroid-android library, thus they were + * put here as more of an example. + * + * + * created on 12/21/2016. + * + * @author Alex O'Ree + * @since 5.6.2 + */ +class SqlTileWriterExt() : SqlTileWriter() { + fun select(rows: Int, offset: Int): Cursor? { + return this.db?.rawQuery( + "select " + DatabaseFileArchive.COLUMN_KEY + "," + COLUMN_EXPIRES + "," + DatabaseFileArchive.COLUMN_PROVIDER + " from " + DatabaseFileArchive.TABLE + " limit ? offset ?", + arrayOf(rows.toString() + "", offset.toString() + "") + ) + } + + /** + * gets all the tiles sources that we have tiles for in the cache database and their counts + * + * @return + */ + val sources: List + get() { + val db = db + val ret: MutableList = ArrayList() + if (db == null) { + return ret + } + var cur: Cursor? = null + try { + cur = db.rawQuery( + "select " + + DatabaseFileArchive.COLUMN_PROVIDER + + ",count(*) " + + ",min(length(" + DatabaseFileArchive.COLUMN_TILE + ")) " + + ",max(length(" + DatabaseFileArchive.COLUMN_TILE + ")) " + + ",sum(length(" + DatabaseFileArchive.COLUMN_TILE + ")) " + + "from " + DatabaseFileArchive.TABLE + " " + + "group by " + DatabaseFileArchive.COLUMN_PROVIDER, null + ) + while (cur.moveToNext()) { + val c = SourceCount() + c.source = cur.getString(0) + c.rowCount = cur.getLong(1) + c.sizeMin = cur.getLong(2) + c.sizeMax = cur.getLong(3) + c.sizeTotal = cur.getLong(4) + c.sizeAvg = c.sizeTotal / c.rowCount + ret.add(c) + } + } catch (e: Exception) { + catchException(e) + } finally { + cur?.close() + } + return ret + } + val rowCountExpired: Long + get() = getRowCount( + "$COLUMN_EXPIRES