fix: remove Realm DB

This commit is contained in:
Akash Yadav
2024-07-20 20:16:47 +05:30
parent 1d68499189
commit f837b9369e
51 changed files with 15 additions and 3383 deletions
-1
View File
@@ -28,7 +28,6 @@ plugins {
id("kotlin-android")
id("kotlin-kapt")
id("kotlin-parcelize")
id("realm-android")
id("androidx.navigation.safeargs.kotlin")
id("com.itsaky.androidide.desugaring")
}
@@ -58,7 +58,6 @@ import com.itsaky.androidide.utils.flashError
import com.termux.app.TermuxApplication
import com.termux.shared.reflection.ReflectionUtils
import io.github.rosemoe.sora.widget.schemes.EditorColorScheme
import io.realm.Realm
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
@@ -110,8 +109,6 @@ class IDEApplication : TermuxApplication() {
EventBus.getDefault().register(this)
Realm.init(this)
AppCompatDelegate.setDefaultNightMode(GeneralPreferences.uiMode)
if (IThemeManager.getInstance().getCurrentTheme() == IDETheme.MATERIAL_YOU) {
-1
View File
@@ -1 +0,0 @@
/build
-41
View File
@@ -1,41 +0,0 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
import com.itsaky.androidide.build.config.BuildConfig
plugins {
id("com.android.library")
id("kotlin-android")
id("kotlin-kapt")
id("realm-android")
}
android {
namespace = "${BuildConfig.packageName}.database"
}
dependencies {
kapt(libs.google.auto.service)
implementation(libs.google.auto.service.annotations)
implementation(projects.core.common)
implementation(projects.logging.logger)
implementation(projects.utilities.shared)
}
View File
-21
View File
@@ -1,21 +0,0 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
@@ -1,91 +0,0 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.db
import com.itsaky.androidide.utils.ServiceLoader
import io.realm.Realm
import io.realm.RealmConfiguration
/**
* An [IRealmProvider] provides the instance of [Realm].
*
* @author Akash Yadav
*/
interface IRealmProvider {
/**
* Get the [Realm] instance.
*
* @param path The path of the database.
*/
fun get(path: String): Realm {
return get(path, null)
}
/**
* Get the [Realm] instance.
*
* @param path The path of the database.
* @param config An optional function to configure the [RealmConfiguration] builder.
*/
fun get(path: String, config: (RealmConfiguration.Builder.() -> Unit)?): Realm
companion object {
private lateinit var sInstance: IRealmProvider
/**
* The separator used to separate segments in an index path.
*/
const val PATH_SEPARATOR = '/'
/**
* Create the path for the given segments.
*
* @param first The first (root) path segment.
* @param rest The rest of the path segments.
* @return The created path string.
*/
@JvmStatic
fun createPath(first: String, vararg rest: String): String {
val sb = StringBuilder()
sb.append(PATH_SEPARATOR)
sb.append(first)
for (segment in rest) {
sb.append(PATH_SEPARATOR)
sb.append(segment)
}
return sb.toString()
}
/**
* Get the [IRealmProvider] instance, finding the implementation if necessary.
*/
@JvmStatic
fun instance(): IRealmProvider {
if (!Companion::sInstance.isInitialized) {
val clazz = IRealmProvider::class.java
sInstance = ServiceLoader.load(clazz, clazz.classLoader).findFirstOrThrow()
}
return sInstance
}
}
}
@@ -1,66 +0,0 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.db.internal
import io.realm.RealmObject
import io.realm.annotations.PrimaryKey
import io.realm.annotations.RealmField
import io.realm.annotations.Required
/**
* An entity to store information about all registered box stores.
*
* @author Akash Yadav
*/
open class DatabaseEntity(
@Required
@PrimaryKey
@RealmField("path")
var path: String = "",
@Required
@RealmField("name")
var name: String = "",
@Required
@RealmField("directory")
var directory: String = "",
) : RealmObject() {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is DatabaseEntity) return false
if (path != other.path) return false
if (name != other.name) return false
if (directory != other.directory) return false
return true
}
override fun hashCode(): Int {
var result = path.hashCode()
result = 31 * result + name.hashCode()
result = 31 * result + directory.hashCode()
return result
}
override fun toString(): String {
return "DatabaseEntity(path='$path', name='$name', directory='$directory')"
}
}
@@ -1,28 +0,0 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.db.internal
import io.realm.annotations.RealmModule
/**
* [RealmModule] for the internal database entitites.
*
* @author Akash Yadav
*/
@RealmModule(library = true, classes = [DatabaseEntity::class])
internal class InternalDBRealmModule
@@ -1,115 +0,0 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.db.internal
import com.google.auto.service.AutoService
import com.itsaky.androidide.db.IRealmProvider
import com.itsaky.androidide.utils.Environment
import io.realm.Realm
import io.realm.RealmConfiguration
import org.slf4j.LoggerFactory
/**
* Default implementation of [IRealmProvider].
*
* @author Akash Yadav
*/
@AutoService(IRealmProvider::class)
@Suppress("unused")
internal class RealmProviderImpl : IRealmProvider {
companion object {
private val log = LoggerFactory.getLogger(RealmProviderImpl::class.java)
// must be a relative path, with no special characters except '_' '-' and '/' (path sep)
private val dbNameRegex = Regex("^[a-zA-Z0-9_\\-/]+$")
private const val MASTER_DB_NAME = "master"
private const val MASTER_DB_PATH = "/$MASTER_DB_NAME"
}
private val masterDb: Realm by lazy {
createDb(MASTER_DB_PATH) {
modules(InternalDBRealmModule())
}
}
override fun get(path: String, config: (RealmConfiguration.Builder.() -> Unit)?): Realm {
require(path != MASTER_DB_PATH) {
"Master DB is internal to AndroidIDE"
}
return createDb(path, config)
}
private fun createDb(path: String, confFunc: (RealmConfiguration.Builder.() -> Unit)?): Realm {
val (parentPath, name) = validateDbPath(path)
val configBuilder = RealmConfiguration.Builder()
confFunc?.also { configure -> configBuilder.configure() }
var dbDir = Environment.REALM_DB_DIR
if (parentPath.isNotEmpty()) {
dbDir = dbDir.resolve(parentPath)
}
val dbName = "${name}.realm"
val config = configBuilder
.name(dbName)
.directory(dbDir)
.allowQueriesOnUiThread(false)
.allowWritesOnUiThread(false)
.compactOnLaunch()
.build()
log.info("Creating DB at $dbDir/$dbName")
if (parentPath.isEmpty() && name != MASTER_DB_NAME) {
masterDb.executeTransactionAsync { realm ->
realm.insertOrUpdate(DatabaseEntity(name = name, path = path, directory = dbDir.absolutePath))
}
}
return Realm.getInstance(config)
}
private fun validateDbPath(path: String): Pair<String, String> {
val idx = path.indexOfLast { it == IRealmProvider.PATH_SEPARATOR }
require(
path.matches(dbNameRegex)
&& path[0] == IRealmProvider.PATH_SEPARATOR
&& idx >= 0
&& path.indexOf("//") == -1
) {
"Invalid DB path: $path"
}
val parentPath = if (idx > 1) {
path.substring(1, idx)
} else ""
val name = path.substring(idx + 1)
if (name == MASTER_DB_NAME) {
require(parentPath.isEmpty()) {
"Master DB must not have any parent path"
}
}
return parentPath to name
}
}
@@ -1,60 +0,0 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.db.utils
import io.realm.RealmDictionary
/**
* Check if two RealmDictionaries are equal.
*/
fun <T> RealmDictionary<out T>?.isEqualTo(other: Any?): Boolean {
// implementation taken from java/util/AbstractMap from JDK 21
if (other == this) return true
if (other == null || this == null) return false
if (other !is RealmDictionary<*>) return false
if (this.size != other.size) return false
try {
for (entry in this.entries) {
val key = entry.key
val value = entry.value
if (value == null) {
if (!(other[key] == null && other.containsKey(key))) {
return false
}
} else {
if (value != other[key]) {
return false
}
}
}
} catch (e: ClassCastException) {
return false
} catch (e: NullPointerException) {
return false
}
return true
}
/**
* Generate the hash code for a RealmDictionary.
*/
fun <T> RealmDictionary<T>.hash(): Int {
return this.entries.sumOf { it.hashCode() }
}
-4
View File
@@ -22,11 +22,8 @@ plugins {
id("com.android.library")
id("kotlin-android")
id("kotlin-kapt")
id("realm-android")
}
android {
namespace = "${BuildConfig.packageName}.indexing.api"
}
@@ -36,7 +33,6 @@ dependencies {
implementation(libs.google.auto.service.annotations)
api(projects.core.common)
api(projects.core.database)
api(projects.core.projects)
api(projects.logging.logger)
api(projects.utilities.shared)
@@ -1,59 +0,0 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.indexing
import io.realm.Realm
/**
* Abstract implementation of [IIndex] for indexing data in the database.
*
* @property params The index parameters.
* @author Akash Yadav
*/
abstract class AbstractDBIndex<T : IIndexable>(
protected val params: IIndexParams?
) : IDatabaseIndex<T> {
protected abstract val realm: Realm
override fun index(symbol: T) {
realm.executeTransaction {
it.insertOrUpdate(symbol)
}
}
override fun indexAsync(symbol: T) {
realm.executeTransactionAsync {
it.insertOrUpdate(symbol)
}
}
override fun indexAll(symbols: Collection<T>) {
realm.executeTransaction {
it.insertOrUpdate(symbols)
}
}
override fun indexAllAsync(symbols: Collection<T>) {
realm.executeTransactionAsync { it.insertOrUpdate(symbols) }
}
override fun delete() {
realm.deleteAll()
}
}
@@ -1,33 +0,0 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.indexing
import io.realm.RealmQuery
/**
* An index which is stored in the database.
*
* @author Akash Yadav
*/
interface IDatabaseIndex<IndexableT : IIndexable> : IIndex<IndexableT> {
/**
* Perform a query on the Realm database.
*/
fun query(): RealmQuery<IndexableT>
}
@@ -17,8 +17,6 @@
package com.itsaky.androidide.indexing
import com.itsaky.androidide.db.IRealmProvider
/**
* An index of symbols of type [IndexableT].
*
@@ -28,6 +26,8 @@ interface IIndex<IndexableT : IIndexable> {
companion object {
const val PATH_SEPARATOR = '/'
/**
* The default batch size for indexing.
*/
@@ -44,7 +44,7 @@ interface IIndex<IndexableT : IIndexable> {
* Create an index path.
*/
fun createIndexPath(parentPath: String, name: String): String =
"${parentPath}${IRealmProvider.PATH_SEPARATOR}${name}"
"${parentPath}${PATH_SEPARATOR}${name}"
}
/**
@@ -17,11 +17,9 @@
package com.itsaky.androidide.indexing
import io.realm.RealmModel
/**
* An indexable object.
*
* @author Akash Yadav
*/
interface IIndexable : RealmModel
interface IIndexable
-3
View File
@@ -22,11 +22,8 @@ plugins {
id("com.android.library")
id("kotlin-android")
id("kotlin-kapt")
id("realm-android")
}
android {
namespace = "${BuildConfig.packageName}.indexing.core"
}
@@ -1,26 +0,0 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.indexing.core
import io.realm.annotations.RealmModule
/**
* @author Akash Yadav
*/
@RealmModule(classes = [])
class IndexingCoreRealmModule