Add Storage Service plugin to Spinner.

This commit is contained in:
Cody Henthorne
2022-06-24 11:07:37 -04:00
parent 9bc25132c3
commit 89a6730efe
13 changed files with 162 additions and 9 deletions

View File

@@ -23,7 +23,8 @@ class MainActivity : AppCompatActivity() {
"Name" to "${Build.MODEL} (API ${Build.VERSION.SDK_INT})",
"Package" to packageName
),
mapOf("main" to Spinner.DatabaseConfig(db = db))
mapOf("main" to Spinner.DatabaseConfig(db = db)),
emptyMap()
)
}

View File

@@ -23,4 +23,7 @@
<li {{#if isBrowse}}class="active"{{/if}}><a href="/browse?db={{database}}">Browse</a></li>
<li {{#if isQuery}}class="active"{{/if}}><a href="/query?db={{database}}">Query</a></li>
<li {{#if isRecent}}class="active"{{/if}}><a href="/recent?db={{database}}">Recent</a></li>
{{#each plugins}}
<li {{#if (eq name activePlugin.name)}}class="active"{{/if}}><a href="{{path}}">{{name}}</a></li>
{{/each}}
</ol>

View File

@@ -0,0 +1,28 @@
<html>
{{> partials/head title=activePlugin.name }}
<body>
{{> partials/prefix}}
{{#if (eq "table" pluginResult.type)}}
<h1>Data</h1>
{{pluginResult.rowCount}} row(s). <br />
<br />
<table>
<tr>
{{#each pluginResult.columns}}
<th>{{this}}</th>
{{/each}}
</tr>
{{#each pluginResult.rows}}
<tr>
{{#each this}}
<td><pre>{{{this}}}</pre></td>
{{/each}}
</tr>
{{/each}}
</table>
{{/if}}
{{> partials/suffix }}
</body>
</html>

View File

@@ -0,0 +1,7 @@
package org.signal.spinner
interface Plugin {
fun get(): PluginResult
val name: String
val path: String
}

View File

@@ -0,0 +1,9 @@
package org.signal.spinner
sealed class PluginResult(val type: String) {
data class TableResult(
val columns: List<String>,
val rows: List<List<String>>,
val rowCount: Int = rows.size,
) : PluginResult("table")
}

View File

@@ -18,9 +18,9 @@ object Spinner {
private lateinit var server: SpinnerServer
fun init(application: Application, deviceInfo: Map<String, String>, databases: Map<String, DatabaseConfig>) {
fun init(application: Application, deviceInfo: Map<String, String>, databases: Map<String, DatabaseConfig>, plugins: Map<String, Plugin>) {
try {
server = SpinnerServer(application, deviceInfo, databases)
server = SpinnerServer(application, deviceInfo, databases, plugins)
server.start()
} catch (e: IOException) {
Log.w(TAG, "Spinner server hit IO exception!", e)

View File

@@ -29,7 +29,8 @@ import kotlin.math.min
internal class SpinnerServer(
private val application: Application,
deviceInfo: Map<String, String>,
private val databases: Map<String, DatabaseConfig>
private val databases: Map<String, DatabaseConfig>,
private val plugins: Map<String, Plugin>
) : NanoHTTPD(5000) {
companion object {
@@ -66,7 +67,14 @@ internal class SpinnerServer(
session.method == Method.GET && session.uri == "/query" -> getQuery(dbParam, dbConfig.db)
session.method == Method.POST && session.uri == "/query" -> postQuery(dbParam, dbConfig, session)
session.method == Method.GET && session.uri == "/recent" -> getRecent(dbParam, dbConfig.db)
else -> newFixedLengthResponse(Response.Status.NOT_FOUND, MIME_HTML, "Not found")
else -> {
val plugin = plugins[session.uri]
if (plugin != null && session.method == Method.GET) {
getPlugin(dbParam, plugin)
} else {
newFixedLengthResponse(Response.Status.NOT_FOUND, MIME_HTML, "Not found")
}
}
}
} catch (t: Throwable) {
Log.e(TAG, t)
@@ -93,6 +101,7 @@ internal class SpinnerServer(
deviceInfo = deviceInfo,
database = dbName,
databases = databases.keys.toList(),
plugins = plugins.values.toList(),
tables = db.getTables().toTableInfo(),
indices = db.getIndexes().toIndexInfo(),
triggers = db.getTriggers().toTriggerInfo(),
@@ -109,6 +118,7 @@ internal class SpinnerServer(
deviceInfo = deviceInfo,
database = dbName,
databases = databases.keys.toList(),
plugins = plugins.values.toList(),
tableNames = db.getTableNames()
)
)
@@ -140,6 +150,7 @@ internal class SpinnerServer(
deviceInfo = deviceInfo,
database = dbName,
databases = databases.keys.toList(),
plugins = plugins.values.toList(),
tableNames = dbConfig.db.getTableNames(),
table = table,
queryResult = queryResult,
@@ -163,6 +174,7 @@ internal class SpinnerServer(
deviceInfo = deviceInfo,
database = dbName,
databases = databases.keys.toList(),
plugins = plugins.values.toList(),
query = ""
)
)
@@ -184,6 +196,7 @@ internal class SpinnerServer(
deviceInfo = deviceInfo,
database = dbName,
databases = databases.keys.toList(),
plugins = plugins.values.toList(),
recentSql = queries?.reversed()
)
)
@@ -202,12 +215,28 @@ internal class SpinnerServer(
deviceInfo = deviceInfo,
database = dbName,
databases = databases.keys.toList(),
plugins = plugins.values.toList(),
query = rawQuery,
queryResult = dbConfig.db.query(query).toQueryResult(queryStartTime = startTime, columnTransformers = dbConfig.columnTransformers)
)
)
}
private fun getPlugin(dbName: String, plugin: Plugin): Response {
return renderTemplate(
"plugin",
PluginPageModel(
environment = environment,
deviceInfo = deviceInfo,
database = dbName,
databases = databases.keys.toList(),
plugins = plugins.values.toList(),
activePlugin = plugin,
pluginResult = plugin.get()
)
)
}
private fun internalError(throwable: Throwable): Response {
val stackTrace = ExceptionUtil.convertThrowableToString(throwable)
.split("\n")
@@ -361,6 +390,7 @@ internal class SpinnerServer(
val deviceInfo: Map<String, String>
val database: String
val databases: List<String>
val plugins: List<Plugin>
}
data class OverviewPageModel(
@@ -368,6 +398,7 @@ internal class SpinnerServer(
override val deviceInfo: Map<String, String>,
override val database: String,
override val databases: List<String>,
override val plugins: List<Plugin>,
val tables: List<TableInfo>,
val indices: List<IndexInfo>,
val triggers: List<TriggerInfo>,
@@ -379,6 +410,7 @@ internal class SpinnerServer(
override val deviceInfo: Map<String, String>,
override val database: String,
override val databases: List<String>,
override val plugins: List<Plugin>,
val tableNames: List<String>,
val table: String? = null,
val queryResult: QueryResult? = null,
@@ -390,6 +422,7 @@ internal class SpinnerServer(
override val deviceInfo: Map<String, String>,
override val database: String,
override val databases: List<String>,
override val plugins: List<Plugin>,
val query: String = "",
val queryResult: QueryResult? = null
) : PrefixPageData
@@ -399,9 +432,20 @@ internal class SpinnerServer(
override val deviceInfo: Map<String, String>,
override val database: String,
override val databases: List<String>,
override val plugins: List<Plugin>,
val recentSql: List<RecentQuery>?
) : PrefixPageData
data class PluginPageModel(
override val environment: String,
override val deviceInfo: Map<String, String>,
override val database: String,
override val databases: List<String>,
override val plugins: List<Plugin>,
val activePlugin: Plugin,
val pluginResult: PluginResult
) : PrefixPageData
data class QueryResult(
val columns: List<String>,
val rows: List<List<String>>,