রুম (কোটলিন মাল্টিপ্ল্যাটফর্ম)

রুম পারসিসটেন্স লাইব্রেরি SQLite এর উপর একটি অ্যাবস্ট্রাকশন লেয়ার প্রদান করে যাতে SQLite এর পূর্ণ শক্তি ব্যবহার করার সময় আরও শক্তিশালী ডাটাবেস অ্যাক্সেসের অনুমতি দেওয়া হয়। এই পৃষ্ঠাটি কোটলিন মাল্টিপ্ল্যাটফর্ম (KMP) প্রকল্পে রুম ব্যবহার করার উপর দৃষ্টি নিবদ্ধ করে। রুম ব্যবহার করার বিষয়ে আরও তথ্যের জন্য, রুম বা আমাদের অফিসিয়াল নমুনা ব্যবহার করে একটি স্থানীয় ডাটাবেসে ডেটা সংরক্ষণ করুন দেখুন।

নির্ভরতা সেট আপ করুন

আপনার KMP প্রোজেক্টে রুম সেটআপ করতে, আপনার KMP মডিউলের জন্য build.gradle.kts ফাইলে আর্টিফ্যাক্টগুলির জন্য নির্ভরতা যোগ করুন।

libs.versions.toml ফাইলে নির্ভরতা সংজ্ঞায়িত করুন:

[versions]
room = "2.7.2"
sqlite = "2.5.2"
ksp = "<kotlinCompatibleKspVersion>"

[libraries]
androidx-sqlite-bundled = { module = "androidx.sqlite:sqlite-bundled", version.ref = "sqlite" }
androidx-room-runtime = { module = "androidx.room:room-runtime", version.ref = "room" }
androidx-room-compiler = { module = "androidx.room:room-compiler", version.ref = "room" }

# Optional SQLite Wrapper available in version 2.8.0 and higher
androidx-room-sqlite-wrapper = { module = "androidx.room:room-sqlite-wrapper", version.ref = "room" }

[plugins]
ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
androidx-room = { id = "androidx.room", version.ref = "room" }

রুম স্কিমা এবং KSP প্লাগইন কনফিগার করতে রুম গ্রেডল প্লাগইন যোগ করুন

plugins {
  alias(libs.plugins.ksp)
  alias(libs.plugins.androidx.room)
}

রুম রানটাইম নির্ভরতা এবং বান্ডিল SQLite লাইব্রেরি যোগ করুন:

commonMain.dependencies {
  implementation(libs.androidx.room.runtime)
  implementation(libs.androidx.sqlite.bundled)
}

// Optional when using Room SQLite Wrapper
androidMain.dependencies {
  implementation(libs.androidx.room.sqlite.wrapper)
}

রুট dependencies ব্লকে KSP নির্ভরতা যোগ করুন। মনে রাখবেন যে আপনার অ্যাপ ব্যবহার করে এমন সব লক্ষ্য যোগ করতে হবে। আরও তথ্যের জন্য, Kotlin মাল্টিপ্ল্যাটফর্মের সাথে KSP চেক করুন।

dependencies {
    add("kspAndroid", libs.androidx.room.compiler)
    add("kspIosSimulatorArm64", libs.androidx.room.compiler)
    add("kspIosX64", libs.androidx.room.compiler)
    add("kspIosArm64", libs.androidx.room.compiler)
    // Add any other platform target you use in your project, for example kspDesktop
}

রুম স্কিমা ডিরেক্টরি সংজ্ঞায়িত করুন। অতিরিক্ত তথ্যের জন্য, রুম গ্রেডল প্লাগইন ব্যবহার করে স্কিমা অবস্থান সেট করুন দেখুন।

room {
    schemaDirectory("$projectDir/schemas")
}

ডাটাবেস ক্লাস সংজ্ঞায়িত করুন

আপনার শেয়ার করা KMP মডিউলের সাধারণ উৎস সেটের ভিতরে DAO এবং সত্তা সহ @Database এর সাথে টীকাযুক্ত একটি ডাটাবেস ক্লাস তৈরি করতে হবে। সাধারণ উত্সগুলিতে এই ক্লাসগুলি স্থাপন করা তাদের সমস্ত লক্ষ্য প্ল্যাটফর্ম জুড়ে ভাগ করার অনুমতি দেবে৷

// shared/src/commonMain/kotlin/Database.kt

@Database(entities = [TodoEntity::class], version = 1)
@ConstructedBy(AppDatabaseConstructor::class)
abstract class AppDatabase : RoomDatabase() {
  abstract fun getDao(): TodoDao
}

// The Room compiler generates the `actual` implementations.
@Suppress("KotlinNoActualForExpect")
expect object AppDatabaseConstructor : RoomDatabaseConstructor<AppDatabase> {
    override fun initialize(): AppDatabase
}

আপনি যখন RoomDatabaseConstructor ইন্টারফেসের সাথে একটি expect বস্তু ঘোষণা করেন, তখন রুম কম্পাইলার actual বাস্তবায়ন তৈরি করে। অ্যান্ড্রয়েড স্টুডিও নিম্নলিখিত সতর্কতা জারি করতে পারে, যা আপনি @Suppress("KotlinNoActualForExpect") দিয়ে দমন করতে পারেন:

Expected object 'AppDatabaseConstructor' has no actual declaration in module`

এর পরে, হয় একটি নতুন DAO ইন্টারফেস সংজ্ঞায়িত করুন বা বিদ্যমান একটিকে commonMain এ সরান:

// shared/src/commonMain/kotlin/TodoDao.kt

@Dao
interface TodoDao {
  @Insert
  suspend fun insert(item: TodoEntity)

  @Query("SELECT count(*) FROM TodoEntity")
  suspend fun count(): Int

  @Query("SELECT * FROM TodoEntity")
  fun getAllAsFlow(): Flow<List<TodoEntity>>
}

আপনার সত্ত্বাকে commonMain এ সংজ্ঞায়িত করুন বা সরান:

// shared/src/commonMain/kotlin/TodoEntity.kt

@Entity
data class TodoEntity(
  @PrimaryKey(autoGenerate = true) val id: Long = 0,
  val title: String,
  val content: String
)

প্ল্যাটফর্ম-নির্দিষ্ট ডাটাবেস নির্মাতা তৈরি করুন

প্রতিটি প্ল্যাটফর্মে রুম ইনস্ট্যান্টিয়েট করার জন্য আপনাকে একটি ডাটাবেস নির্মাতাকে সংজ্ঞায়িত করতে হবে। এটি API-এর একমাত্র অংশ যা ফাইল সিস্টেম API-এর পার্থক্যের কারণে প্ল্যাটফর্ম-নির্দিষ্ট উৎস সেটে থাকা প্রয়োজন।

অ্যান্ড্রয়েড

অ্যান্ড্রয়েডে, ডাটাবেসের অবস্থান সাধারণত Context.getDatabasePath() API-এর মাধ্যমে পাওয়া যায়। ডাটাবেস ইনস্ট্যান্স তৈরি করতে, ডাটাবেস পাথ সহ একটি Context উল্লেখ করুন।

// shared/src/androidMain/kotlin/Database.android.kt

fun getDatabaseBuilder(context: Context): RoomDatabase.Builder<AppDatabase> {
  val appContext = context.applicationContext
  val dbFile = appContext.getDatabasePath("my_room.db")
  return Room.databaseBuilder<AppDatabase>(
    context = appContext,
    name = dbFile.absolutePath
  )
}

iOS

iOS-এ ডাটাবেস ইনস্ট্যান্স তৈরি করতে, NSFileManager ব্যবহার করে একটি ডাটাবেস পাথ প্রদান করুন, সাধারণত NSDocumentDirectory এ অবস্থিত।

// shared/src/iosMain/kotlin/Database.ios.kt

fun getDatabaseBuilder(): RoomDatabase.Builder<AppDatabase> {
    val dbFilePath = documentDirectory() + "/my_room.db"
    return Room.databaseBuilder<AppDatabase>(
        name = dbFilePath,
    )
}

private fun documentDirectory(): String {
  val documentDirectory = NSFileManager.defaultManager.URLForDirectory(
    directory = NSDocumentDirectory,
    inDomain = NSUserDomainMask,
    appropriateForURL = null,
    create = false,
    error = null,
  )
  return requireNotNull(documentDirectory?.path)
}

JVM (ডেস্কটপ)

ডাটাবেস ইনস্ট্যান্স তৈরি করতে, জাভা বা কোটলিন API ব্যবহার করে একটি ডাটাবেস পাথ প্রদান করুন।

// shared/src/jvmMain/kotlin/Database.desktop.kt

fun getDatabaseBuilder(): RoomDatabase.Builder<AppDatabase> {
    val dbFile = File(System.getProperty("java.io.tmpdir"), "my_room.db")
    return Room.databaseBuilder<AppDatabase>(
        name = dbFile.absolutePath,
    )
}

ডাটাবেস ইনস্ট্যান্টিয়েট করুন

একবার আপনি প্ল্যাটফর্ম-নির্দিষ্ট কনস্ট্রাক্টরগুলির একটি থেকে RoomDatabase.Builder প্রাপ্ত করার পরে, আপনি প্রকৃত ডাটাবেস ইনস্ট্যান্টেশনের সাথে সাধারণ কোডে রুম ডাটাবেসের বাকি অংশ কনফিগার করতে পারেন।

// shared/src/commonMain/kotlin/Database.kt

fun getRoomDatabase(
    builder: RoomDatabase.Builder<AppDatabase>
): AppDatabase {
  return builder
      .setDriver(BundledSQLiteDriver())
      .setQueryCoroutineContext(Dispatchers.IO)
      .build()
}

একটি SQLite ড্রাইভার নির্বাচন করুন

পূর্ববর্তী কোড স্নিপেটটি setDriver বিল্ডার ফাংশনকে কল করে যে SQLite ড্রাইভারটি রুম ডাটাবেস ব্যবহার করা উচিত তা নির্ধারণ করতে। এই ড্রাইভারগুলি লক্ষ্য প্ল্যাটফর্মের উপর ভিত্তি করে পৃথক। পূর্ববর্তী কোড স্নিপেট BundledSQLiteDriver ব্যবহার করে। এটি একটি প্রস্তাবিত ড্রাইভার যা উৎস থেকে সংকলিত SQLite অন্তর্ভুক্ত করে, যা সমস্ত প্ল্যাটফর্ম জুড়ে SQLite-এর সবচেয়ে সামঞ্জস্যপূর্ণ এবং আপ-টু-ডেট সংস্করণ প্রদান করে।

আপনি যদি OS-প্রদত্ত SQLite ব্যবহার করতে চান, তাহলে প্ল্যাটফর্ম-নির্দিষ্ট উৎস সেটগুলিতে setDriver API ব্যবহার করুন যা একটি প্ল্যাটফর্ম-নির্দিষ্ট ড্রাইভার নির্দিষ্ট করে। উপলব্ধ ড্রাইভার বাস্তবায়নের বর্ণনার জন্য ড্রাইভার বাস্তবায়ন দেখুন। আপনি নিম্নলিখিত যে কোনো একটি ব্যবহার করতে পারেন:

NativeSQLiteDriver ব্যবহার করতে, আপনাকে একটি লিঙ্কার বিকল্প -lsqlite3 প্রদান করতে হবে যাতে iOS অ্যাপটি গতিশীলভাবে SQLite সিস্টেমের সাথে লিঙ্ক করে।

// shared/build.gradle.kts

kotlin {
    listOf(
        iosX64(),
        iosArm64(),
        iosSimulatorArm64()
    ).forEach { iosTarget ->
        iosTarget.binaries.framework {
            baseName = "TodoApp"
            isStatic = true
            // Required when using NativeSQLiteDriver
            linkerOpts.add("-lsqlite3")
        }
    }
}

একটি করোটিন প্রসঙ্গ সেট করুন (ঐচ্ছিক)

অ্যান্ড্রয়েডে একটি RoomDatabase অবজেক্ট ঐচ্ছিকভাবে ডাটাবেস ক্রিয়াকলাপ সম্পাদন করতে RoomDatabase.Builder.setQueryExecutor() ব্যবহার করে ভাগ করা অ্যাপ্লিকেশন নির্বাহকদের সাথে কনফিগার করা যেতে পারে।

কারণ নির্বাহক KMP সামঞ্জস্যপূর্ণ নয়, রুমের setQueryExecutor() API commonMain এ উপলব্ধ নয়। পরিবর্তে RoomDatabase অবজেক্ট একটি CoroutineContext দিয়ে কনফিগার করা আবশ্যক, যা RoomDatabase.Builder.setCoroutineContext() ব্যবহার করে সেট করা যেতে পারে। যদি কোন প্রসঙ্গ সেট করা না থাকে, তাহলে RoomDatabase অবজেক্ট ডিফল্ট হবে Dispatchers.IO ব্যবহার করে।

ক্ষুদ্রকরণ এবং অস্পষ্টতা

যদি প্রকল্পটি ছোট করা হয় বা অস্পষ্ট হয় তবে আপনাকে অবশ্যই নিম্নলিখিত ProGuard নিয়মটি অন্তর্ভুক্ত করতে হবে যাতে রুম ডেটাবেস সংজ্ঞার জেনারেটেড বাস্তবায়ন খুঁজে পেতে পারে:

-keep class * extends androidx.room.RoomDatabase { <init>(); }

কোটলিন মাল্টিপ্ল্যাটফর্মে স্থানান্তর করুন

রুমটি মূলত একটি অ্যান্ড্রয়েড লাইব্রেরি হিসাবে তৈরি করা হয়েছিল এবং পরে API সামঞ্জস্যের উপর ফোকাস রেখে কেএমপিতে স্থানান্তরিত করা হয়েছিল। প্ল্যাটফর্ম এবং অ্যান্ড্রয়েড-নির্দিষ্ট সংস্করণ থেকে রুমের KMP সংস্করণ কিছুটা আলাদা। এই পার্থক্যগুলি নিম্নরূপ তালিকাভুক্ত এবং বর্ণনা করা হয়েছে।

Support SQLite থেকে SQLite Driver-এ স্থানান্তর করুন

androidx.sqlite.dbSupportSQLiteDatabase এবং অন্যান্য API-এর যেকোনো ব্যবহারকে SQLite Driver API-এর সাথে রিফ্যাক্টর করতে হবে, কারণ androidx.sqlite.db এর APIগুলি শুধুমাত্র অ্যান্ড্রয়েড (KMP প্যাকেজের চেয়ে আলাদা প্যাকেজ নোট করুন)।

পিছনের দিকে সামঞ্জস্যের জন্য, এবং যতক্ষণ পর্যন্ত RoomDatabase একটি SupportSQLiteOpenHelper.Factory দিয়ে কনফিগার করা হয় (উদাহরণস্বরূপ, কোন SQLiteDriver সেট করা নেই), তখন রুম 'কম্প্যাটিবিলিটি মোডে' আচরণ করে যেখানে Support SQLite এবং SQLite Driver API উভয়ই প্রত্যাশিতভাবে কাজ করে। এটি ক্রমবর্ধমান স্থানান্তর সক্ষম করে যাতে আপনাকে আপনার সমস্ত সমর্থন SQLite ব্যবহারগুলিকে একক পরিবর্তনে SQLite ড্রাইভারে রূপান্তর করতে হবে না।

মাইগ্রেশন সাবক্লাসে রূপান্তর করুন

মাইগ্রেশন সাবক্লাসগুলি SQLite ড্রাইভারের প্রতিরূপগুলিতে স্থানান্তরিত করা প্রয়োজন:

কোটলিন মাল্টিপ্ল্যাটফর্ম

মাইগ্রেশন সাবক্লাস

object Migration_1_2 : Migration(1, 2) {
  override fun migrate(connection: SQLiteConnection) {
    // …
  }
}

অটো মাইগ্রেশন স্পেসিফিকেশন সাবক্লাস

class AutoMigrationSpec_1_2 : AutoMigrationSpec {
  override fun onPostMigrate(connection: SQLiteConnection) {
    // …
  }
}

শুধুমাত্র অ্যান্ড্রয়েড

মাইগ্রেশন সাবক্লাস

object Migration_1_2 : Migration(1, 2) {
  override fun migrate(db: SupportSQLiteDatabase) {
    // …
  }
}

অটো মাইগ্রেশন স্পেসিফিকেশন সাবক্লাস

class AutoMigrationSpec_1_2 : AutoMigrationSpec {
  override fun onPostMigrate(db: SupportSQLiteDatabase) {
    // …
  }
}

ডাটাবেস কলব্যাক রূপান্তর

ডেটাবেস কলব্যাকগুলি SQLite ড্রাইভারের প্রতিরূপগুলিতে স্থানান্তরিত করা প্রয়োজন:

কোটলিন মাল্টিপ্ল্যাটফর্ম

object MyRoomCallback : RoomDatabase.Callback() {
  override fun onCreate(connection: SQLiteConnection) {
    // …
  }

  override fun onDestructiveMigration(connection: SQLiteConnection) {
    // …
  }

  override fun onOpen(connection: SQLiteConnection) {
    // …
  }
}

শুধুমাত্র অ্যান্ড্রয়েড

object MyRoomCallback : RoomDatabase.Callback() {
  override fun onCreate(db: SupportSQLiteDatabase) {
    // …
  }

  override fun onDestructiveMigration(db: SupportSQLiteDatabase) {
    // …
  }

  override fun onOpen(db: SupportSQLiteDatabase) {
    // …
  }
}

@RawQuery DAO ফাংশন রূপান্তর করুন

@RawQuery সাথে টীকাযুক্ত ফাংশনগুলি যেগুলি নন-Android প্ল্যাটফর্মগুলির জন্য কম্পাইল করা হয়েছে, SupportSQLiteQuery এর পরিবর্তে RoomRawQuery টাইপের একটি প্যারামিটার ঘোষণা করতে হবে।

কোটলিন মাল্টিপ্ল্যাটফর্ম

কাঁচা প্রশ্ন সংজ্ঞায়িত করুন

@Dao
interface TodoDao {
  @RawQuery
  suspend fun getTodos(query: RoomRawQuery): List<TodoEntity>
}

রানটাইমে একটি ক্যোয়ারী তৈরি করতে একটি RoomRawQuery ব্যবহার করা যেতে পারে:

suspend fun AppDatabase.getTodosWithLowercaseTitle(title: String): List<TodoEntity> {
    val query = RoomRawQuery(
        sql = "SELECT * FROM TodoEntity WHERE title = ?",
        onBindStatement = {
            it.bindText(1, title.lowercase())
        }
    )

    return todoDao().getTodos(query)
}

শুধুমাত্র অ্যান্ড্রয়েড

কাঁচা প্রশ্ন সংজ্ঞায়িত করুন

@Dao
interface TodoDao {
  @RawQuery
  suspend fun getTodos(query: SupportSQLiteQuery): List<TodoEntity>
}

রানটাইমে একটি প্রশ্ন তৈরি করতে একটি SimpleSQLiteQuery ব্যবহার করা যেতে পারে:

suspend fun AndroidOnlyDao.getTodosWithLowercaseTitle(title: String): List<TodoEntity> {
  val query = SimpleSQLiteQuery(
      query = "SELECT * FROM TodoEntity WHERE title = ?",
      bindArgs = arrayOf(title.lowercase())
  )
  return getTodos(query)
}

ব্লকিং DAO ফাংশন রূপান্তর করুন

বৈশিষ্ট্য-সমৃদ্ধ অ্যাসিঙ্ক্রোনাস kotlinx.coroutines লাইব্রেরি থেকে রুম সুবিধা যা Kotlin একাধিক প্ল্যাটফর্মের জন্য অফার করে। সর্বোত্তম কার্যকারিতার জন্য, বিদ্যমান কোডবেসের সাথে পিছনের সামঞ্জস্য বজায় রাখার জন্য androidMain এ বাস্তবায়িত DAO ব্যতীত একটি KMP প্রকল্পে সংকলিত DAO-এর জন্য suspend ফাংশন প্রয়োগ করা হয়। KMP-এর জন্য রুম ব্যবহার করার সময়, নন-অ্যান্ড্রয়েড প্ল্যাটফর্মগুলির জন্য কম্পাইল করা সমস্ত DAO ফাংশনগুলিকে suspend ফাংশন হতে হবে।

কোটলিন মাল্টিপ্ল্যাটফর্ম

প্রশ্ন স্থগিত করা হচ্ছে

@Query("SELECT * FROM Todo")
suspend fun getAllTodos(): List<Todo>

লেনদেন স্থগিত করা

@Transaction
suspend fun transaction() {  }

শুধুমাত্র অ্যান্ড্রয়েড

প্রশ্ন ব্লক করা

@Query("SELECT * FROM Todo")
fun getAllTodos(): List<Todo>

লেনদেন ব্লক করা

@Transaction
fun blockingTransaction() {  }

প্রতিক্রিয়াশীল প্রকারগুলিকে ফ্লোতে রূপান্তর করুন

সমস্ত DAO ফাংশন সাসপেন্ড ফাংশন হতে হবে না। DAO ফাংশনগুলি যেগুলি প্রতিক্রিয়াশীল প্রকারগুলি প্রদান করে যেমন LiveData বা RxJava's Flowable সাসপেন্ড ফাংশনে রূপান্তরিত করা উচিত নয়৷ কিছু প্রকার, যেমন LiveData KMP সামঞ্জস্যপূর্ণ নয়। প্রতিক্রিয়াশীল রিটার্ন প্রকারের সাথে DAO ফাংশনগুলিকে অবশ্যই কোরোটিন প্রবাহে স্থানান্তরিত করতে হবে।

কোটলিন মাল্টিপ্ল্যাটফর্ম

প্রতিক্রিয়াশীল প্রকারগুলি Flows

@Query("SELECT * FROM Todo")
fun getTodosFlow(): Flow<List<Todo>>

শুধুমাত্র অ্যান্ড্রয়েড

LiveData বা RxJava এর Flowable মত প্রতিক্রিয়াশীল প্রকার

@Query("SELECT * FROM Todo")
fun getTodosLiveData(): LiveData<List<Todo>>

লেনদেন APIs রূপান্তর

রুম KMP-এর জন্য ডেটাবেস লেনদেন APIগুলি লেখার ( useWriterConnection ) এবং পড়ার ( useReaderConnection ) লেনদেনের মধ্যে পার্থক্য করতে পারে৷

কোটলিন মাল্টিপ্ল্যাটফর্ম

val database: RoomDatabase = 
database.useWriterConnection { transactor ->
  transactor.immediateTransaction {
    // perform database operations in transaction
  }
}

শুধুমাত্র অ্যান্ড্রয়েড

val database: RoomDatabase = 
database.withTransaction {
  // perform database operations in transaction
}

লেনদেন লিখুন

একাধিক ক্যোয়ারী পারমাণবিকভাবে ডেটা লেখার বিষয়টি নিশ্চিত করতে লিখিত লেনদেন ব্যবহার করুন, যাতে পাঠকরা ধারাবাহিকভাবে ডেটা অ্যাক্সেস করতে পারে। আপনি useWriterConnection ব্যবহার করে তিনটি লেনদেনের প্রকারের যেকোনোটির সাথে এটি করতে পারেন:

  • immediateTransaction : Write-Ahead Logging (WAL) মোডে (ডিফল্ট), এই ধরনের লেনদেন শুরু হলে একটি লক হয়ে যায়, কিন্তু পাঠকরা পড়া চালিয়ে যেতে পারেন। এটি বেশিরভাগ ক্ষেত্রেই পছন্দের পছন্দ।

  • deferredTransaction : প্রথম লেখা বিবৃতি না দেওয়া পর্যন্ত লেনদেন একটি লক অর্জন করবে না। এই ধরনের লেনদেন একটি অপ্টিমাইজেশান হিসাবে ব্যবহার করুন যখন আপনি নিশ্চিত না হন যে লেনদেনের মধ্যে একটি লেখার অপারেশন প্রয়োজন হবে কিনা৷ উদাহরণস্বরূপ, যদি আপনি প্লেলিস্টের শুধুমাত্র একটি নাম দেওয়া একটি প্লেলিস্ট থেকে গানগুলি মুছে ফেলার জন্য একটি লেনদেন শুরু করেন এবং প্লেলিস্টটি বিদ্যমান না থাকে, তাহলে কোন লেখা (মুছুন) অপারেশনের প্রয়োজন নেই৷

  • exclusiveTransaction : এই মোডটি WAL মোডে immediateTransaction মতো আচরণ করে। অন্যান্য জার্নালিং মোডে, এটি লেনদেন চলাকালীন অন্যান্য ডাটাবেস সংযোগগুলিকে ডাটাবেস পড়তে বাধা দেয়।

লেনদেন পড়ুন

ডাটাবেস থেকে ধারাবাহিকভাবে একাধিকবার পড়তে পঠিত লেনদেন ব্যবহার করুন। উদাহরণস্বরূপ, যখন আপনার দুটি বা ততোধিক পৃথক প্রশ্ন থাকে এবং আপনি একটি JOIN ধারা ব্যবহার করেন না। পাঠক সংযোগে শুধুমাত্র বিলম্বিত লেনদেন অনুমোদিত। একটি পাঠক সংযোগে একটি অবিলম্বে বা একচেটিয়া লেনদেন শুরু করার প্রচেষ্টা একটি ব্যতিক্রম ছুঁড়ে দেবে, কারণ এগুলিকে 'লিখন' ক্রিয়াকলাপ হিসাবে বিবেচনা করা হয়৷

val database: RoomDatabase = 
database.useReaderConnection { transactor ->
  transactor.deferredTransaction {
      // perform database operations in transaction
  }
}

কোটলিন মাল্টিপ্ল্যাটফর্মে উপলব্ধ নয়

অ্যান্ড্রয়েডের জন্য উপলব্ধ কিছু এপিআই কোটলিন মাল্টিপ্ল্যাটফর্মে উপলব্ধ নয়।

কলব্যাক জিজ্ঞাসা করুন

ক্যোয়ারী কলব্যাক কনফিগার করার জন্য নিম্নলিখিত APIগুলি সাধারণভাবে উপলব্ধ নয় এবং এইভাবে Android ছাড়া অন্য প্ল্যাটফর্মগুলিতে অনুপলব্ধ৷

  • RoomDatabase.Builder.setQueryCallback
  • RoomDatabase.QueryCallback

আমরা রুমের ভবিষ্যত সংস্করণে কোয়েরি কলব্যাকের জন্য সমর্থন যোগ করতে চাই।

একটি ক্যোয়ারী কলব্যাক RoomDatabase.Builder.setQueryCallback সহ কলব্যাক ইন্টারফেস RoomDatabase.QueryCallback সহ একটি RoomDatabase কনফিগার করার API সাধারণভাবে উপলব্ধ নয় এবং এইভাবে Android ছাড়া অন্য প্ল্যাটফর্মে উপলব্ধ নয়৷

অটো ক্লোজিং ডাটাবেস

টাইমআউটের পরে স্বয়ংক্রিয়ভাবে বন্ধ করার জন্য API, RoomDatabase.Builder.setAutoCloseTimeout , শুধুমাত্র Android এ উপলব্ধ এবং অন্যান্য প্ল্যাটফর্মগুলিতে উপলব্ধ নয়৷

প্রাক-প্যাকেজ ডাটাবেস

একটি বিদ্যমান ডাটাবেস (যেমন একটি প্রাক-প্যাকেজ করা ডাটাবেস) ব্যবহার করে একটি RoomDatabase তৈরি করার জন্য নিম্নলিখিত APIগুলি সাধারণভাবে উপলব্ধ নয় এবং তাই অ্যান্ড্রয়েড ছাড়া অন্য প্ল্যাটফর্মগুলিতে উপলব্ধ নয়৷ এই APIগুলি হল:

  • RoomDatabase.Builder.createFromAsset
  • RoomDatabase.Builder.createFromFile
  • RoomDatabase.Builder.createFromInputStream
  • RoomDatabase.PrepackagedDatabaseCallback

আমরা রুমের ভবিষ্যত সংস্করণে প্রাক-প্যাকেজ করা ডাটাবেসের জন্য সমর্থন যোগ করতে চাই।

মাল্টি-ইনস্ট্যান্স অবৈধকরণ

মাল্টি-ইনস্ট্যান্স অবৈধকরণ সক্ষম করার API, RoomDatabase.Builder.enableMultiInstanceInvalidation শুধুমাত্র Android এ উপলব্ধ এবং সাধারণ বা অন্যান্য প্ল্যাটফর্মে উপলব্ধ নয়৷

{% শব্দার্থে %} {% endverbatim %} {% শব্দার্থে %} {% endverbatim %}