Skip to content

Commit

Permalink
Add experimental wasm-open-helper library (draft) (#276)
Browse files Browse the repository at this point in the history
* Add experimental wasm-open-helper library (draft)
  • Loading branch information
illarionov authored May 15, 2024
1 parent a78dc8e commit af0d712
Show file tree
Hide file tree
Showing 20 changed files with 545 additions and 21 deletions.
8 changes: 8 additions & 0 deletions feature/calendar/data/calendar-data.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
plugins {
id("ru.pixnews.gradle.android.library")
id("ru.pixnews.gradle.di.anvil-factories")
id("ru.pixnews.gradle.test.graalvm")
}

pixnews {
Expand Down Expand Up @@ -36,4 +37,11 @@ dependencies {
testImplementation(projects.library.test)
testImplementation(libs.junit.jupiter.params)
testImplementation(libs.androidx.paging.testing)
testImplementation(libs.pixnews.sqlite.open.helper.main)
testImplementation(libs.pixnews.sqlite.open.helper.graal)
testImplementation(libs.pixnews.sqlite.open.helper.chicory)
testImplementation(libs.pixnews.sqlite.open.helper.chasm)

testImplementation(libs.pixnews.sqlite.open.helper.sqlite.mt)
testImplementation(libs.pixnews.sqlite.open.helper.sqlite.st)
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import ru.pixnews.feature.calendar.data.sync.policy.SyncPolicy
import ru.pixnews.feature.calendar.data.sync.policy.SyncRequiredResult
import ru.pixnews.feature.calendar.data.sync.policy.isSyncRequired
import ru.pixnews.foundation.database.PixnewsDatabase
import ru.pixnews.foundation.database.entity.mode.GameModeEntity
import ru.pixnews.foundation.database.entity.mode.GameModeNameEntity
import ru.pixnews.foundation.database.model.LanguageCodeWrapper
import ru.pixnews.foundation.di.base.scopes.AppScope
Expand Down Expand Up @@ -130,8 +129,7 @@ public class IgdbGameModeSyncService(
return@withTransaction
}
for (mode in modes) {
val gameModeEntity = GameModeEntity(slug = mode.igdbSlug)
val id = gameModeDao.insertOrGetId(gameModeEntity)
val id = gameModeDao.insertOrGetId(mode.igdbSlug)
if (id != -1L) {
val nameEntity = GameModeNameEntity(
gameModeId = id,
Expand Down
12 changes: 12 additions & 0 deletions feature/calendar/data/src/test/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (c) 2024, the Pixnews project authors and contributors. Please see the AUTHORS file for details.
Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">

<uses-sdk
android:minSdkVersion="26"
tools:overrideLibrary="ru.pixnews.wasm.sqlite.open.helper" />
</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* Copyright (c) 2024, the Pixnews project authors and contributors. Please see the AUTHORS file for details.
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
*/

package ru.pixnews.feature.calendar.data.sync

import android.content.ContextWrapper
import androidx.room.Room
import androidx.room.RoomDatabase.JournalMode.WRITE_AHEAD_LOGGING
import co.touchlab.kermit.LoggerConfig
import co.touchlab.kermit.Severity
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.io.TempDir
import ru.pixnews.foundation.database.PixnewsDatabase
import ru.pixnews.foundation.database.util.QueryLogger
import ru.pixnews.library.test.TestingLoggers
import ru.pixnews.wasm.sqlite.open.helper.SQLiteDatabaseJournalMode.PERSIST
import ru.pixnews.wasm.sqlite.open.helper.SQLiteDatabaseSyncMode
import ru.pixnews.wasm.sqlite.open.helper.WasmSqliteOpenHelperFactory
import ru.pixnews.wasm.sqlite.open.helper.graalvm.GraalvmSqliteEmbedder
import ru.pixnews.wasm.sqlite.open.helper.path.JvmDatabasePathResolver
import java.io.File
import co.touchlab.kermit.Logger as KermitLogger

class IgdbGameModeSyncServiceTest {
val logger = TestingLoggers.consoleLogger
val mockContext = ContextWrapper(null)

@TempDir
lateinit var tempDir: File
lateinit var db: PixnewsDatabase

@BeforeEach
fun createDb() {
val dbLogger = KermitLogger(
config = object : LoggerConfig by logger.config {
override val minSeverity: Severity = Severity.Info
},
"Sqlite",
)

val helperFactory = WasmSqliteOpenHelperFactory(GraalvmSqliteEmbedder) {
logger = SqliteLogger(dbLogger)
pathResolver = JvmDatabasePathResolver(tempDir)
openParams {
journalMode = PERSIST
syncMode = SQLiteDatabaseSyncMode.OFF
}
debug {
sqlLog = false
sqlStatements = false
sqlTime = false
logSlowQueries = false
}
}

db = Room.databaseBuilder(
mockContext,
PixnewsDatabase::class.java,
"pixnews",
)
.setJournalMode(WRITE_AHEAD_LOGGING)
// .createFromAsset("pixnews.db")
.setQueryCallback(QueryLogger(logger), QueryLogger.createLoggerExecutor())
.openHelperFactory(helperFactory)
.allowMainThreadQueries()
.build()
}

@AfterEach
fun closeDb() {
db.close()
}

@Test
fun dbTest() {
val gameMode = db.gameModeNameDao().getByIdTestBlocking(1)
logger.i { "gem mode: $gameMode" }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* Copyright (c) 2024, the Pixnews project authors and contributors. Please see the AUTHORS file for details.
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
*/

package ru.pixnews.feature.calendar.data.sync

import co.touchlab.kermit.Logger
import ru.pixnews.wasm.sqlite.open.helper.common.api.Logger as WasmHelperLogger

@Suppress("IDENTIFIER_LENGTH")
internal class SqliteLogger(
private val kermitLogger: Logger,
) : WasmHelperLogger {
override fun a(throwable: Throwable?, message: () -> String) {
if (throwable != null) {
kermitLogger.a(throwable, message)
} else {
kermitLogger.a(message)
}
}

override fun d(throwable: Throwable?, message: () -> String) {
if (throwable != null) {
kermitLogger.d(throwable, message)
} else {
kermitLogger.d(message)
}
}

override fun e(throwable: Throwable?, message: () -> String) {
if (throwable != null) {
kermitLogger.e(throwable, message)
} else {
kermitLogger.e(message)
}
}

override fun i(throwable: Throwable?, message: () -> String) {
if (throwable != null) {
kermitLogger.i(throwable, message)
} else {
kermitLogger.i(message)
}
}

override fun v(throwable: Throwable?, message: () -> String) {
if (throwable != null) {
kermitLogger.v(throwable, message)
} else {
kermitLogger.v(message)
}
}

override fun w(throwable: Throwable?, message: () -> String) {
if (throwable != null) {
kermitLogger.w(throwable, message)
} else {
kermitLogger.w(message)
}
}

override fun withTag(tag: String): WasmHelperLogger {
return SqliteLogger(kermitLogger.withTag(tag))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@
package ru.pixnews.foundation.database.dao

import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.Transaction
import ru.pixnews.foundation.database.entity.mode.GameModeEntity

@Dao
public abstract class GameModeDao {
@Insert(onConflict = OnConflictStrategy.IGNORE)
public abstract suspend fun insertSilent(gameMode: GameModeEntity): Long
@Query("INSERT OR IGNORE INTO `gameMode`(`slug`) VALUES(:slug)")
public abstract suspend fun insertSlug(slug: String): Long

@Query("SELECT * FROM `gameMode` WHERE `id` = :id")
public abstract suspend fun getById(id: Long): GameModeEntity?
Expand All @@ -25,12 +24,13 @@ public abstract class GameModeDao {
@Query("SELECT `id` FROM `gameMode` WHERE `slug` = :slug")
public abstract suspend fun getIdBySlug(slug: String): Long?

public suspend fun insertOrGetId(
gameMode: GameModeEntity,
@Transaction
public open suspend fun insertOrGetId(
slug: String,
): Long {
val id = insertSilent(gameMode)
val id = insertSlug(slug)
return if (id == -1L) {
getIdBySlug(gameMode.slug) ?: -1
getIdBySlug(slug) ?: -1
} else {
id
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.Transaction
import androidx.room.Update
import ru.pixnews.foundation.database.entity.mode.GameModeNameEntity
import ru.pixnews.foundation.database.model.LanguageCodeWrapper

Expand All @@ -19,12 +18,24 @@ public abstract class GameModeNameDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
public abstract suspend fun insertGameModeName(gameModeName: GameModeNameEntity): Long

@Update(onConflict = OnConflictStrategy.IGNORE)
public abstract suspend fun updateGameModeName(gameModeName: GameModeNameEntity)
@Query(
"UPDATE OR IGNORE `gameModeName` " +
"SET name = :name " +
"WHERE gameModeId = :gameModeId " +
"AND languageCode = :languageCode",
)
public abstract suspend fun updateGameModeName(
gameModeId: Long,
languageCode: LanguageCodeWrapper,
name: String,
)

@Query("SELECT * FROM `gameModeName` WHERE `id` = :id")
public abstract suspend fun getById(id: Long): GameModeNameEntity?

@Query("SELECT * FROM `gameModeName` WHERE `id` = :id")
public abstract fun getByIdTestBlocking(id: Long): GameModeNameEntity?

@Query(
"SELECT `gameModeName`.* " +
"FROM `gameModeName` " +
Expand Down Expand Up @@ -61,7 +72,11 @@ public abstract class GameModeNameDao {
): Long {
val old = getByGameIdAndLanguage(gameModeName.gameModeId, gameModeName.languageCode)
return if (old != null) {
updateGameModeName(gameModeName.copy(id = old.id))
updateGameModeName(
gameModeId = gameModeName.gameModeId,
languageCode = gameModeName.languageCode,
name = gameModeName.name,
)
old.id
} else {
insertGameModeName(gameModeName)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import androidx.room.RoomDatabase
import co.touchlab.kermit.Logger
import java.util.concurrent.Executor

internal class QueryLogger(
public class QueryLogger(
logger: Logger,
) : RoomDatabase.QueryCallback {
private val logger = logger.withTag("Pixnews SQL")
Expand All @@ -25,7 +25,7 @@ internal class QueryLogger(
logger.d(msg)
}

internal companion object {
fun createLoggerExecutor(): Executor = Executor { command -> command.run() }
public companion object {
public fun createLoggerExecutor(): Executor = Executor { command -> command.run() }
}
}
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ org.gradle.jvmargs=-Dfile.encoding=UTF-8 \
-Xmx2G -XX:MaxMetaspaceSize=1G -XX:SoftRefLRUPolicyMSPerMB=10 -XX:+UseParallelGC \
-XX:+HeapDumpOnOutOfMemoryError
kotlin.daemon.jvmargs=-Dfile.encoding=UTF-8 \
-Xmx2G -XX:MaxMetaspaceSize=320M -XX:SoftRefLRUPolicyMSPerMB=10 -XX:+UseParallelGC -XX:NewRatio=1 \
-Xmx4G -XX:MaxMetaspaceSize=320M -XX:SoftRefLRUPolicyMSPerMB=10 -XX:+UseParallelGC -XX:NewRatio=1 \
-XX:+HeapDumpOnOutOfMemoryError

org.gradle.parallel=true
Expand Down
10 changes: 9 additions & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,13 @@ arrow = "1.2.4"
assertk = "0.28.1"
debuglayout = "0.1"
asm = "9.6"
auto-service = "1.1.1"
coil = "2.6.0"
fbase-gradle-plugin = "0.1"
firebase-bom = "33.0.0"
firebase-crashlytics-plugin = "2.9.0"
igdbclient = "0.5"
guava = "31.1-jre"
graalvm = "24.0.1"
kermit = "1.2.3"
kotest = "5.9.0"
kotest-assertions-arrow = "1.4.0"
Expand All @@ -78,6 +78,7 @@ prefiller = "1.6.0-SNAPSHOT"
retrofit = "2.9.0"
radiography = "2.6"
turbine = "1.1.0"
wasm-sqlite-open-helper = "0.1-alpha03"

junit4 = "4.13.2"
junit5 = "5.10.2"
Expand Down Expand Up @@ -158,6 +159,7 @@ firebase-bom = { group = "com.google.firebase", name = "firebase-bom", version.r
firebase-analytics = { group = "com.google.firebase", name = "firebase-analytics-ktx" }
firebase-config = { group = "com.google.firebase", name = "firebase-config-ktx" }
firebase-crashlytics = { group = "com.google.firebase", name = "firebase-crashlytics-ktx" }
graalvm-compiler = { group = "org.graalvm.compiler", name = "compiler", version.ref = "graalvm" }
guava-bom = { group = "com.google.guava", name = "guava-bom", version.ref = "guava" }
igdbclient = { group = "ru.pixnews.igdbclient", name = "igdbclient-core", version.ref = "igdbclient" }
igdbclient-okhttp = { group = "ru.pixnews.igdbclient", name = "igdbclient-okhttp", version.ref = "igdbclient" }
Expand Down Expand Up @@ -204,6 +206,12 @@ pixnews-anvil-viewmodel-inject = { group = "ru.pixnews.anvil.codegen", name = "v
pixnews-anvil-workmanager-generator = { group = "ru.pixnews.anvil.codegen", name = "workmanager-generator", version.ref = "pixnews-anvil-codegen" }
pixnews-anvil-workmanager-inject = { group = "ru.pixnews.anvil.codegen", name = "workmanager-inject", version.ref = "pixnews-anvil-codegen" }
pixnews-debuglayout = { group = "ru.pixnews.debuglayout", name = "core", version.ref = "debuglayout" }
pixnews-sqlite-open-helper-main = { group = "ru.pixnews.wasm-sqlite-open-helper", name = "sqlite-open-helper", version.ref = "wasm-sqlite-open-helper" }
pixnews-sqlite-open-helper-graal = { group = "ru.pixnews.wasm-sqlite-open-helper", name = "sqlite-embedder-graalvm", version.ref = "wasm-sqlite-open-helper" }
pixnews-sqlite-open-helper-chicory = { group = "ru.pixnews.wasm-sqlite-open-helper", name = "sqlite-embedder-chicory", version.ref = "wasm-sqlite-open-helper" }
pixnews-sqlite-open-helper-chasm = { group = "ru.pixnews.wasm-sqlite-open-helper", name = "sqlite-embedder-chasm", version.ref = "wasm-sqlite-open-helper" }
pixnews-sqlite-open-helper-sqlite-mt = { group = "ru.pixnews.wasm-sqlite-open-helper", name = "sqlite-android-wasm-emscripten-icu-mt-pthread-345", version.ref = "wasm-sqlite-open-helper" }
pixnews-sqlite-open-helper-sqlite-st = { group = "ru.pixnews.wasm-sqlite-open-helper", name = "sqlite-android-wasm-emscripten-icu-345", version.ref = "wasm-sqlite-open-helper" }
radiography = { group = "com.squareup.radiography", name = "radiography", version.ref = "radiography" }
turbine = { group = "app.cash.turbine", name = "turbine", version.ref = "turbine" }
wire-runtime-jvm = { group = "com.squareup.wire", name = "wire-runtime-jvm", version.ref = "wire" }
Expand Down
1 change: 1 addition & 0 deletions gradle/plugin/project/settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ includeSubproject("kotlin")
includeSubproject("lint")
includeSubproject("protobuf")
includeSubproject("testing")
includeSubproject("testing-graalvm")

fun includeSubproject(path: String) {
include(path)
Expand Down
Loading

0 comments on commit af0d712

Please sign in to comment.