Android Question Sqlite Ai-sync Integration to b4a

Pearl

Member
Hello B4X Community,

This is my first thread ...

While looking for a offline-first db solution for b4a beside cloudkvs I came across this

(https://github.com/sqliteai/sqlite-sync)

As Erel has mentioned in a thread by default, Android OS does not support loading SQLite extensions (such as .so files) the same way as standard desktop SQLite. This means you can’t simply load an extension with load_extension or similar commands out-of-the-box in Android.

Yesterday sqliteai team updated its github and has added a doc for android integration.
This is how they work around it.

SQLite Sync Integration Guide for Android

This guide shows how to integrate SQLite Sync into your Android application. Since extension loading is disabled by default in Android's SQLite implementation, you need an alternative SQLite library that supports extensions.

This example uses the `requery:sqlite-android` library, but other options include building a custom SQLite with extension support or using other third-party SQLite libraries that enable extension loading.

1. Add Dependencies
In your `app/build.gradle.kts`:
Code:
dependencies {
    implementation("com.github.requery:sqlite-android:3.49.0")
}

2. Bundle the Extension
Place your `cloudsync.so` file in:
`app/src/main/assets/lib/cloudsync.so`

3. Basic Integration
Java:
import android.content.Context
import androidx.activity.ComponentActivity
import androidx.lifecycle.lifecycleScope
import io.requery.android.database.sqlite.SQLiteCustomExtension
import io.requery.android.database.sqlite.SQLiteCustomFunction
import io.requery.android.database.sqlite.SQLiteDatabase
import io.requery.android.database.sqlite.SQLiteDatabaseConfiguration
import io.requery.android.database.sqlite.SQLiteFunction
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.File
import java.io.FileOutputStream

class MainActivity : ComponentActivity() {
    private fun copyExtensionToFilesDir(context: Context): File {
        val assetManager = context.assets
        val inputStream = assetManager.open("lib/cloudsync.so")

        val outFile = File(context.filesDir, "cloudsync.so")
        inputStream.use { input ->
            FileOutputStream(outFile).use { output ->
                input.copyTo(output)
            }
        }
        return outFile
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
      
        // Copy extension from assets to filesystem
        val extensionFile = copyExtensionToFilesDir(this)
        val extensionPath = extensionFile.absolutePath
      
        // Create extension configuration
        val cloudSyncExtension = SQLiteCustomExtension(extensionPath, null)

        // Configure database with extension
        val config = SQLiteDatabaseConfiguration(
            "${filesDir.path}/test.db",
            SQLiteDatabase.CREATE_IF_NECESSARY or SQLiteDatabase.OPEN_READWRITE,
            emptyList<SQLiteCustomFunction>(),
            emptyList<SQLiteFunction>(),
            listOf(cloudSyncExtension)
        )

        // Open database
        val db = SQLiteDatabase.openDatabase(config, null, null)

        // Test extension loading
        lifecycleScope.launch {
            withContext(Dispatchers.IO) {
                val cursor = db.rawQuery("SELECT cloudsync_version();", null)
                val version = if (cursor.moveToFirst()) cursor.getString(0) else null
                cursor.close()

                if (version != null) {
                    println("SQLite Sync loaded successfully. Version: $version")

Can anyone help me in converting above solution for b4a?

My goals are:
- Synchronize a local SQLite database on an Android device with a remote database/server using sqlite-sync.

Has anyone successfully used sqlite-sync with B4A? If so:
- Could you share sample code, libraries, or wrapper suggestions?
- Are there any B4A-specific caveats or things to watch out for? YES I know about Cloudkvs & Wmsynctable by walt61.

Here is the .aar file for requery sqlite android for wrapping

https://repo1.maven.org/maven2/io/requery/requery-android/1.6.0/



Greetings.
 
Last edited:

Pearl

Member
Oops there is also a sub forum "Libraries developers questions". I think this thread should have been posted there..@Erel any comment on thread subject.
 
Upvote 0

ernschd

Active Member
Licensed User
Longtime User
Hello, I came through your thread to https://www.powersync.com. It uses a server database (Postgres, MongoDB, MySQL) as the backend for synchronization. In my opinion, the advantage over SQLite Sync is that it is an open source project and can also be used without a cloud. This puts you on the safe side in case the provider discontinues the service at some point. Would this solution also be of interest to you? Then we could try to develop an integration for B4A together.
 
Upvote 0

Pearl

Member
Hello, I came through your thread to https://www.powersync.com. It uses a server database (Postgres, MongoDB, MySQL) as the backend for synchronization. In my opinion, the advantage over SQLite Sync is that it is an open source project and can also be used without a cloud. This puts you on the safe side in case the provider discontinues the service at some point. Would this solution also be of interest to you? Then we could try to develop an integration for B4A together.
Thank you for your interest. Honestly I was about create a new thread about Powersync as this sqlite-ai would require a whole new wrapper for this custom query-sqlite & I hope some one with good java kotlin knowledge would do this one day....

I came across Powersync well before this when @Alexander Stolte initially started posting about Supabase as Powersync can easily be connected to supabase project. Powersync offers multiple client side SDKs. I once started integrating kotlin example to b4a but due to my lack of knowledge about kotlin/java I couldn't complete it.

I believe B4X staff should consider implementing an offline-first solution with support for a CRDT-based database & Powersync is one of the best options.

I think we should create a new thread about Powersync so that more members join and contribute to it what do you think?

Best regards
 
Upvote 0

ernschd

Active Member
Licensed User
Longtime User
Hi Pearl,

yes, creating a new thread is a good idea.
I would do a test with PowerSync and standard Android development first before trying a wrapper. So far I'm not that familiar with Kotlin/Java development either.

Best regards
 
Upvote 0
Top