Skip to content
This repository was archived by the owner on Oct 24, 2025. It is now read-only.

Commit 482fd7b

Browse files
committed
initial android module + js
1 parent 1336687 commit 482fd7b

File tree

11 files changed

+392
-139
lines changed

11 files changed

+392
-139
lines changed

android/build.gradle.kts

Lines changed: 68 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,92 +1,99 @@
11
buildscript {
2-
val kotlinVersion = (rootProject.extra["kotlinVersion"] as String?) ?: "1.9.21"
2+
val kotlinVersion = (rootProject.extra["kotlinVersion"] as String?) ?: "1.9.21"
33

4-
repositories {
5-
google()
6-
mavenCentral()
7-
}
4+
repositories {
5+
google()
6+
mavenCentral()
7+
}
88

9-
dependencies {
10-
classpath("com.android.tools.build:gradle:7.3.1")
11-
// noinspection DifferentKotlinGradleVersion
12-
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
13-
}
9+
dependencies {
10+
classpath("com.android.tools.build:gradle:7.3.1")
11+
// noinspection DifferentKotlinGradleVersion
12+
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
13+
}
1414
}
1515

1616

1717
plugins {
18-
id("com.android.library")
19-
kotlin("android")
20-
id("com.facebook.react").apply(false)
18+
id("com.android.library")
19+
kotlin("android")
20+
id("com.facebook.react").apply(false)
2121
}
2222

2323
if (isNewArchitectureEnabled()) {
24-
apply(plugin = "com.facebook.react")
24+
apply(plugin = "com.facebook.react")
2525
}
2626

2727
android {
28-
if (supportsNamespace()) {
29-
namespace = "org.asyncstorage.sqlite"
30-
}
31-
32-
buildFeatures {
33-
buildConfig = true
34-
}
35-
36-
kotlin {
37-
jvmToolchain(11)
38-
}
39-
40-
lint {
41-
disable += "GradleCompatible"
42-
}
43-
44-
defaultConfig {
45-
compileSdk = getExtraIntOrDefault("compileSdkVersion", 34)
46-
minSdk = getExtraIntOrDefault("minSdkVersion", 21)
47-
buildConfigField(
48-
"boolean",
49-
"IS_NEW_ARCHITECTURE_ENABLED",
50-
isNewArchitectureEnabled().toString()
51-
)
52-
}
53-
54-
sourceSets {
55-
all {
56-
if (isNewArchitectureEnabled()) {
57-
kotlin.srcDirs("src/newarch/kotlin", "${project.buildDir}/generated/source/codegen/java")
58-
} else {
59-
kotlin.srcDirs("src/oldarch/kotlin")
60-
}
28+
if (supportsNamespace()) {
29+
namespace = "org.asyncstorage.sqlite"
30+
}
31+
32+
buildFeatures {
33+
buildConfig = true
34+
}
35+
36+
kotlin {
37+
jvmToolchain(11)
38+
}
39+
40+
lint {
41+
disable += "GradleCompatible"
42+
}
43+
44+
defaultConfig {
45+
compileSdk = getExtraIntOrDefault("compileSdkVersion", 34)
46+
minSdk = getExtraIntOrDefault("minSdkVersion", 21)
47+
buildConfigField(
48+
"boolean",
49+
"IS_NEW_ARCHITECTURE_ENABLED",
50+
isNewArchitectureEnabled().toString()
51+
)
52+
}
53+
54+
sourceSets {
55+
all {
56+
if (isNewArchitectureEnabled()) {
57+
kotlin.srcDirs(
58+
"src/newarch/kotlin",
59+
"${project.buildDir}/generated/source/codegen/java"
60+
)
61+
} else {
62+
kotlin.srcDirs("src/oldarch/kotlin")
63+
}
64+
}
6165
}
62-
}
6366
}
6467

6568
repositories {
66-
mavenCentral()
67-
google()
69+
mavenCentral()
70+
google()
6871
}
6972

7073
dependencies {
71-
// For < 0.71, this will be from the local maven repo
72-
// For > 0.71, this will be replaced by `com.facebook.react:react-android:$version` by react gradle plugin
73-
//noinspection GradleDynamicVersion
74-
implementation("com.facebook.react:react-native:+")
74+
// For < 0.71, this will be from the local maven repo
75+
// For > 0.71, this will be replaced by `com.facebook.react:react-android:$version` by react gradle plugin
76+
//noinspection GradleDynamicVersion
77+
implementation("com.facebook.react:react-native:+")
78+
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0-RC2")
79+
implementation(files("../nativeLib/sqlite-storage-0.0.0.aar"))
80+
implementation("app.cash.sqldelight:android-driver:2.0.1")
81+
7582
}
7683

7784
fun supportsNamespace(): Boolean {
78-
val parsed = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION.split(".")
79-
val major = parsed[0].toInt()
80-
val minor = parsed[1].toInt()
81-
// Namespace support was added in 7.3.0
82-
return (major == 7 && minor >= 3) || major >= 8
85+
val parsed = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION.split(".")
86+
val major = parsed[0].toInt()
87+
val minor = parsed[1].toInt()
88+
// Namespace support was added in 7.3.0
89+
return (major == 7 && minor >= 3) || major >= 8
8390
}
8491

8592
fun isNewArchitectureEnabled() = getExtraOrDefault("newArchEnabled", "false") == "true"
8693

8794

8895
fun getExtraOrDefault(name: String, default: String) =
89-
rootProject.extra.properties.getOrDefault(name, default).toString()
96+
rootProject.extra.properties.getOrDefault(name, default).toString()
9097

9198
fun getExtraIntOrDefault(name: String, default: Int) =
92-
(rootProject.extra.properties[name]?.toString()?.toInt()) ?: default
99+
(rootProject.extra.properties[name]?.toString()?.toInt()) ?: default
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package org.asyncstorage.sqlite
2+
3+
import com.facebook.react.bridge.ReadableArray
4+
import com.facebook.react.bridge.ReadableMap
5+
import com.facebook.react.bridge.WritableNativeArray
6+
import com.facebook.react.bridge.WritableNativeMap
7+
import org.asyncstorage.sqlitestorage.models.Entry
8+
import org.asyncstorage.sqlitestorage.models.Key
9+
import org.asyncstorage.sqlitestorage.models.Value
10+
11+
12+
fun List<Entry>.toReadableMap(): ReadableMap {
13+
val map = WritableNativeMap()
14+
15+
forEach {
16+
map.putString(it.key, it.value)
17+
}
18+
19+
return map
20+
}
21+
22+
fun Entry.toReadableMap(): ReadableMap = WritableNativeMap().apply {
23+
putString(key, value)
24+
}
25+
26+
fun List<Key>.toReadableArray() = WritableNativeArray().apply {
27+
forEach {
28+
this.pushString(it)
29+
}
30+
}
31+
32+
fun ReadableMap.toEntryList(): List<Entry> {
33+
val entries = mutableListOf<Entry>()
34+
35+
for (entry in this.entryIterator) {
36+
entries.add(
37+
Entry(entry.key, entry.value as Value)
38+
)
39+
}
40+
return entries
41+
}
42+
43+
44+
fun ReadableArray.toKeyList() = toArrayList().toList() as List<Key>
Lines changed: 88 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,93 @@
11
package org.asyncstorage.sqlite
22

3-
import kotlin.random.Random
43

4+
import android.content.Context
5+
import com.facebook.react.bridge.Promise
6+
import kotlinx.coroutines.CoroutineScope
7+
import kotlinx.coroutines.Dispatchers
8+
import kotlinx.coroutines.launch
9+
import org.asyncstorage.sqlitestorage.SqliteStorage
10+
import org.asyncstorage.sqlitestorage.SqliteStorageFactory
11+
import org.asyncstorage.sqlitestorage.models.Entry
12+
import org.asyncstorage.sqlitestorage.models.Key
13+
import java.util.concurrent.ConcurrentHashMap
514

6-
class AsyncStorageSqlite {
7-
companion object {
8-
const val NAME = "AsyncStorageSqlite"
9-
}
1015

11-
fun random() = Random.nextInt(0, 100)
12-
}
16+
class AsyncStorageSqlite(ctx: Context) {
17+
private val storages: ConcurrentHashMap<String, SqliteStorage> = ConcurrentHashMap()
18+
private val factory = SqliteStorageFactory(ctx)
19+
private val scope = CoroutineScope(Dispatchers.Default)
20+
21+
22+
fun read(dbName: String, keys: List<String>, promise: Promise) = withStorage(dbName, promise) {
23+
if (keys.isEmpty()) {
24+
return@withStorage false
25+
}
26+
val result = readMany(keys)
27+
result.toReadableMap()
28+
}
29+
30+
fun store(dbName: String, values: List<Entry>, promise: Promise) =
31+
withStorage(dbName, promise) {
32+
if (values.isEmpty()) {
33+
return@withStorage false
34+
}
35+
writeMany(values)
36+
true
37+
}
38+
39+
fun delete(dbName: String, keys: List<Key>, promise: Promise) = withStorage(dbName, promise) {
40+
if (keys.isEmpty()) {
41+
return@withStorage false
42+
}
43+
removeMany(keys)
44+
true
45+
}
46+
47+
fun merge(dbName: String, entries: List<Entry>, promise: Promise) =
48+
withStorage(dbName, promise) {
49+
val result = mergeMany(entries)
50+
result.toReadableMap()
51+
}
52+
53+
fun drop(dbName: String, promise: Promise) = withStorage(dbName, promise) {
54+
dropStorage(dbName)
55+
}
56+
57+
fun keys(dbName: String, promise: Promise) = withStorage(dbName, promise) {
58+
getKeys().toReadableArray()
59+
}
60+
61+
fun absolutePath(dbName: String, promise: Promise) = withStorage(dbName, promise) {
62+
getDbPath()
63+
}
64+
65+
fun fileSize(dbName: String, promise: Promise) = withStorage(dbName, promise) {
66+
val size = getDbSize()
67+
size.toInt()
68+
}
69+
70+
71+
private fun <R> withStorage(
72+
dbName: String,
73+
promise: Promise,
74+
block: suspend SqliteStorage.() -> R
75+
) {
76+
scope.launch {
77+
val storage = storages.getOrPut(dbName) { factory.create(dbName) }
78+
val result = storage.block()
79+
promise.resolve(result)
80+
}
81+
}
82+
83+
private suspend fun dropStorage(dbName: String) {
84+
storages.getOrDefault(dbName, null)?.let {
85+
it.closeConnection()
86+
storages.remove(dbName)
87+
}
88+
}
89+
90+
companion object {
91+
const val NAME = "AsyncStorageSqlite"
92+
}
93+
}

android/src/main/kotlin/org/asyncstorage/sqlite/AsyncStorageSqlitePackage.kt

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,28 +7,28 @@ import com.facebook.react.module.model.ReactModuleInfo
77
import com.facebook.react.module.model.ReactModuleInfoProvider
88

99
class AsyncStorageSqlitePackage : TurboReactPackage() {
10-
override fun getModule(name: String?, ctx: ReactApplicationContext?): NativeModule? {
11-
if (name == AsyncStorageSqlite.NAME) {
12-
return AsyncStorageSqliteModule()
10+
override fun getModule(name: String?, ctx: ReactApplicationContext): NativeModule? {
11+
if (name == AsyncStorageSqlite.NAME) {
12+
return AsyncStorageSqliteModule(ctx)
13+
}
14+
return null
1315
}
14-
return null
15-
}
1616

1717

18-
override fun getReactModuleInfoProvider(): ReactModuleInfoProvider {
19-
return ReactModuleInfoProvider {
20-
val moduleInfo = ReactModuleInfo(
21-
AsyncStorageSqlite.NAME, /* name */
22-
AsyncStorageSqlite::class.java.name, /* className */
23-
false, /* canOverrideExistingModule */
24-
false, /* needsEagerInit */
25-
false, /* hasConstants */
26-
false, /* isCxxModule */
27-
BuildConfig.IS_NEW_ARCHITECTURE_ENABLED, /* isTurboModule */
28-
)
29-
mutableMapOf<String, ReactModuleInfo>().apply {
30-
put(AsyncStorageSqlite.NAME, moduleInfo)
31-
}
18+
override fun getReactModuleInfoProvider(): ReactModuleInfoProvider {
19+
return ReactModuleInfoProvider {
20+
val moduleInfo = ReactModuleInfo(
21+
AsyncStorageSqlite.NAME, /* name */
22+
AsyncStorageSqlite::class.java.name, /* className */
23+
false, /* canOverrideExistingModule */
24+
false, /* needsEagerInit */
25+
false, /* hasConstants */
26+
false, /* isCxxModule */
27+
BuildConfig.IS_NEW_ARCHITECTURE_ENABLED, /* isTurboModule */
28+
)
29+
mutableMapOf<String, ReactModuleInfo>().apply {
30+
put(AsyncStorageSqlite.NAME, moduleInfo)
31+
}
32+
}
3233
}
33-
}
34-
}
34+
}

0 commit comments

Comments
 (0)