mirror of
https://github.com/openflocon/Flocon.git
synced 2026-05-07 19:58:35 +00:00
Feat log db query (#471)
Co-authored-by: Florent Champigny <florent@bere.al>
This commit is contained in:
parent
20b7b7b29c
commit
24bb623ebd
48 changed files with 8659 additions and 129 deletions
|
|
@ -19,6 +19,15 @@ fun floconRegisterDatabase(displayName: String, absolutePath: String) {
|
|||
)
|
||||
}
|
||||
|
||||
fun floconLogDatabaseQuery(dbName: String, sqlQuery: String, bindArgs: List<Any?>) {
|
||||
FloconApp.instance?.client?.databasePlugin?.logQuery(
|
||||
dbName = dbName,
|
||||
sqlQuery = sqlQuery,
|
||||
bindArgs = bindArgs,
|
||||
)
|
||||
}
|
||||
|
||||
interface FloconDatabasePlugin {
|
||||
fun register(floconDatabaseModel: FloconDatabaseModel)
|
||||
fun logQuery(dbName: String, sqlQuery: String, bindArgs: List<Any?>)
|
||||
}
|
||||
|
|
@ -34,6 +34,7 @@ object Protocol {
|
|||
object Method {
|
||||
const val Query = "query"
|
||||
const val GetDatabases = "getDatabases"
|
||||
const val LogQuery = "logQuery"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ import io.github.openflocon.flocon.plugins.database.model.fromdevice.QueryResult
|
|||
import io.github.openflocon.flocon.plugins.database.model.fromdevice.listDeviceDataBaseDataModelToJson
|
||||
import io.github.openflocon.flocon.plugins.database.model.fromdevice.toJson
|
||||
import io.github.openflocon.flocon.plugins.database.model.todevice.DatabaseQueryMessage
|
||||
import io.github.openflocon.flocon.plugins.database.model.fromdevice.DatabaseQueryLogModel
|
||||
import io.github.openflocon.flocon.utils.currentTimeMillis
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
|
||||
|
|
@ -94,4 +96,21 @@ internal class FloconDatabasePluginImpl(
|
|||
registeredDatabases.update { it + floconDatabaseModel }
|
||||
sendAllDatabases(sender)
|
||||
}
|
||||
|
||||
override fun logQuery(dbName: String, sqlQuery: String, bindArgs: List<Any?>) {
|
||||
try {
|
||||
sender.send(
|
||||
plugin = Protocol.FromDevice.Database.Plugin,
|
||||
method = Protocol.FromDevice.Database.Method.LogQuery,
|
||||
body = DatabaseQueryLogModel(
|
||||
dbName = dbName,
|
||||
sqlQuery = sqlQuery,
|
||||
bindArgs = bindArgs.map { it.toString() },
|
||||
timestamp = currentTimeMillis(),
|
||||
).toJson(),
|
||||
)
|
||||
} catch (t: Throwable) {
|
||||
FloconLogger.logError("Database logging error", t)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package io.github.openflocon.flocon.plugins.database.model.fromdevice
|
||||
|
||||
import io.github.openflocon.flocon.core.FloconEncoder
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.encodeToString
|
||||
|
||||
@Serializable
|
||||
internal data class DatabaseQueryLogModel(
|
||||
val dbName: String,
|
||||
val sqlQuery: String,
|
||||
val bindArgs: List<String>?,
|
||||
val timestamp: Long,
|
||||
) {
|
||||
fun toJson(): String {
|
||||
return FloconEncoder.json.encodeToString<DatabaseQueryLogModel>(this)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun fromJson(json: String): DatabaseQueryLogModel {
|
||||
return FloconEncoder.json.decodeFromString<DatabaseQueryLogModel>(json)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -16,7 +16,9 @@ import androidx.compose.foundation.layout.padding
|
|||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.github.openflocon.flocon.Flocon
|
||||
import io.github.openflocon.flocon.FloconLogger
|
||||
|
|
@ -24,6 +26,7 @@ import io.github.openflocon.flocon.myapplication.dashboard.initializeDashboard
|
|||
import io.github.openflocon.flocon.myapplication.database.DogDatabase
|
||||
import io.github.openflocon.flocon.myapplication.database.initializeDatabases
|
||||
import io.github.openflocon.flocon.myapplication.database.initializeInMemoryDatabases
|
||||
import io.github.openflocon.flocon.myapplication.database.model.DogEntity
|
||||
import io.github.openflocon.flocon.myapplication.deeplinks.initializeDeeplinks
|
||||
import io.github.openflocon.flocon.myapplication.graphql.GraphQlTester
|
||||
import io.github.openflocon.flocon.myapplication.grpc.GrpcController
|
||||
|
|
@ -95,6 +98,9 @@ class MainActivity : ComponentActivity() {
|
|||
setContent {
|
||||
MyApplicationTheme {
|
||||
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
|
||||
val scope = rememberCoroutineScope()
|
||||
val context = LocalContext.current
|
||||
|
||||
Column(Modifier.fillMaxSize().padding(innerPadding)) {
|
||||
FlowRow(
|
||||
modifier = Modifier
|
||||
|
|
@ -188,6 +194,23 @@ class MainActivity : ComponentActivity() {
|
|||
) {
|
||||
Text("send analytics event")
|
||||
}
|
||||
Button(
|
||||
onClick = {
|
||||
scope.launch {
|
||||
DogDatabase.getDatabase(context).dogDao().insertDog(
|
||||
DogEntity(
|
||||
id = System.currentTimeMillis(),
|
||||
name = "Flocon",
|
||||
breed = "Golden Retriever ${System.currentTimeMillis()}",
|
||||
age = 6,
|
||||
pictureUrl = "https://picsum.photos/501/500.jpg",
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
) {
|
||||
Text("Insert dog in DB")
|
||||
}
|
||||
}
|
||||
|
||||
ImagesListView(modifier = Modifier.fillMaxSize())
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ import io.github.openflocon.flocon.myapplication.database.dao.DogDao
|
|||
import io.github.openflocon.flocon.myapplication.database.model.DogEntity
|
||||
import io.github.openflocon.flocon.myapplication.database.model.HumanEntity
|
||||
import io.github.openflocon.flocon.myapplication.database.model.HumanWithDogEntity
|
||||
import io.github.openflocon.flocon.plugins.database.floconLogDatabaseQuery
|
||||
import java.util.concurrent.Executors
|
||||
|
||||
@Database(
|
||||
entities = [
|
||||
|
|
@ -26,12 +28,17 @@ abstract class DogDatabase : RoomDatabase() {
|
|||
private var INSTANCE: DogDatabase? = null
|
||||
|
||||
fun getDatabase(context: Context): DogDatabase {
|
||||
val dbName = "dogs_database"
|
||||
return INSTANCE ?: synchronized(this) {
|
||||
val instance = Room.databaseBuilder(
|
||||
context.applicationContext,
|
||||
DogDatabase::class.java,
|
||||
"dogs_database" // Nom du fichier de la base de données Dogs
|
||||
).fallbackToDestructiveMigration().build()
|
||||
dbName
|
||||
).setQueryCallback({ sqlQuery, bindArgs -> floconLogDatabaseQuery(
|
||||
dbName = dbName, sqlQuery = sqlQuery, bindArgs = bindArgs
|
||||
) }, Executors.newSingleThreadExecutor())
|
||||
.fallbackToDestructiveMigration()
|
||||
.build()
|
||||
INSTANCE = instance
|
||||
instance
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,20 +2,29 @@ package io.github.openflocon.flocon.myapplication.multi
|
|||
|
||||
import android.content.Context
|
||||
import androidx.room.Room
|
||||
import androidx.room.RoomDatabase
|
||||
import io.github.openflocon.flocon.myapplication.multi.database.DogDatabase
|
||||
import io.github.openflocon.flocon.myapplication.multi.database.FoodDatabase
|
||||
import io.github.openflocon.flocon.plugins.database.floconLogDatabaseQuery
|
||||
import java.util.concurrent.Executor
|
||||
import java.util.concurrent.Executors
|
||||
|
||||
object Databases {
|
||||
@Volatile
|
||||
private var dogDatabase: DogDatabase? = null
|
||||
|
||||
fun getDogDatabase(context: Context): DogDatabase {
|
||||
val dbName = "dogs_database"
|
||||
return dogDatabase ?: synchronized(this) {
|
||||
val instance = Room.databaseBuilder(
|
||||
context.applicationContext,
|
||||
DogDatabase::class.java,
|
||||
"dogs_database"
|
||||
).fallbackToDestructiveMigration().build()
|
||||
)
|
||||
.setQueryCallback({ sqlQuery, bindArgs -> floconLogDatabaseQuery(
|
||||
dbName = dbName, sqlQuery = sqlQuery, bindArgs = bindArgs
|
||||
) }, Executors.newSingleThreadExecutor())
|
||||
.fallbackToDestructiveMigration().build()
|
||||
dogDatabase = instance
|
||||
instance
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,10 +12,13 @@ import io.github.openflocon.flocon.myapplication.multi.Databases.getDogDatabase
|
|||
import io.github.openflocon.flocon.myapplication.multi.Databases.getFoodDatabase
|
||||
import io.github.openflocon.flocon.myapplication.multi.database.FoodDatabase
|
||||
import io.github.openflocon.flocon.myapplication.multi.database.initializeDatabases
|
||||
import io.github.openflocon.flocon.myapplication.multi.database.model.DogEntity
|
||||
import io.github.openflocon.flocon.myapplication.multi.sharedpreferences.initializeSharedPreferences
|
||||
import io.github.openflocon.flocon.myapplication.multi.ui.App
|
||||
import io.ktor.client.HttpClient
|
||||
import io.ktor.client.engine.okhttp.OkHttp
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class MainActivity : ComponentActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
|
|
@ -43,8 +46,11 @@ class MainActivity : ComponentActivity() {
|
|||
DummyHttpKtorCaller.initialize(ktorClient)
|
||||
|
||||
initializeSharedPreferences(applicationContext)
|
||||
|
||||
val dogDatabase = getDogDatabase(this)
|
||||
|
||||
initializeDatabases(
|
||||
dogDatabase = getDogDatabase(this),
|
||||
dogDatabase = dogDatabase,
|
||||
foodDatabase = getFoodDatabase(this),
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -16,11 +16,14 @@ import androidx.compose.ui.Modifier
|
|||
import androidx.compose.ui.unit.dp
|
||||
import io.github.openflocon.flocon.myapplication.multi.DummyHttpKtorCaller
|
||||
import io.github.openflocon.flocon.myapplication.multi.dashboard.initializeDashboard
|
||||
import io.github.openflocon.flocon.myapplication.multi.database.model.DogEntity
|
||||
import io.github.openflocon.flocon.plugins.analytics.floconAnalytics
|
||||
import io.github.openflocon.flocon.plugins.analytics.model.AnalyticsEvent
|
||||
import io.github.openflocon.flocon.plugins.analytics.model.analyticsProperty
|
||||
import io.github.openflocon.flocon.plugins.tables.floconTable
|
||||
import io.github.openflocon.flocon.plugins.tables.model.toParam
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlin.random.Random
|
||||
|
||||
@Composable
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue