KMP के लिए SQLite सेट अप करना

androidx.sqlite लाइब्रेरी में, ऐब्स्ट्रैक्ट इंटरफ़ेस के साथ-साथ बुनियादी तरीके भी शामिल हैं. इनका इस्तेमाल करके, SQLite को ऐक्सेस करने वाली अपनी लाइब्रेरी बनाई जा सकती हैं. Room लाइब्रेरी का इस्तेमाल किया जा सकता है. यह SQLite को लेकर एक ऐब्स्ट्रैक्शन लेयर उपलब्ध कराती है, ताकि डेटाबेस को ज़्यादा अच्छे से ऐक्सेस किया जा सके. साथ ही, SQLite की पूरी क्षमता का इस्तेमाल किया जा सके.

डिपेंडेंसी सेट अप करना

अपने केएमपी प्रोजेक्ट में SQLite सेट अप करने के लिए, अपने मॉड्यूल की build.gradle.kts फ़ाइल में आर्टफ़ैक्ट के लिए डिपेंडेंसी जोड़ें:

[versions]
sqlite = "2.6.2"

[libraries]
# The SQLite Driver interfaces
androidx-sqlite = { module = "androidx.sqlite:sqlite", version.ref = "sqlite" }

# The bundled SQLite driver implementation
androidx-sqlite-bundled = { module = "androidx.sqlite:sqlite-bundled", version.ref = "sqlite" }

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

SQLite ड्राइवर एपीआई

androidx.sqlite लाइब्रेरी ग्रुप, SQLite लाइब्रेरी के साथ कम्यूनिकेट करने के लिए, लो-लेवल एपीआई उपलब्ध कराते हैं. ये एपीआई, androidx.sqlite:sqlite-bundled का इस्तेमाल करने पर लाइब्रेरी में शामिल होते हैं. वहीं, Android या iOS जैसे होस्ट प्लैटफ़ॉर्म में, androidx.sqlite:sqlite-framework का इस्तेमाल करने पर, ये एपीआई शामिल होते हैं. ये एपीआई, SQLite C API की मुख्य सुविधाओं के मुताबिक काम करते हैं.

इसके तीन मुख्य इंटरफ़ेस हैं:

  • SQLiteDriver - यह SQLite का इस्तेमाल करने का एंट्री पॉइंट है. साथ ही, यह डेटाबेस कनेक्शन खोलने के लिए भी ज़िम्मेदार है.
  • SQLiteConnection - यह sqlite3 ऑब्जेक्ट का प्रतिनिधित्व करता है.
  • SQLiteStatement - यह sqlite3_stmt ऑब्जेक्ट का प्रतिनिधित्व करता है.

यहां दिए गए उदाहरण में, मुख्य एपीआई दिखाए गए हैं:

fun main() {
  val databaseConnection = BundledSQLiteDriver().open("todos.db")
  databaseConnection.execSQL(
    "CREATE TABLE IF NOT EXISTS Todo (id INTEGER PRIMARY KEY, content TEXT)"
  )
  databaseConnection.prepare(
    "INSERT OR IGNORE INTO Todo (id, content) VALUES (? ,?)"
  ).use { stmt ->
    stmt.bindInt(index = 1, value = 1)
    stmt.bindText(index = 2, value = "Try Room in the KMP project.")
    stmt.step()
  }
  databaseConnection.prepare("SELECT content FROM Todo").use { stmt ->
    while (stmt.step()) {
      println("Action item: ${stmt.getText(0)}")
    }
  }
  databaseConnection.close()
}

SQLite C API की तरह, इनका सामान्य इस्तेमाल इस तरह किया जाता है:

  • इंस्टैंशिएट किए गए SQLiteDriver को लागू करके, डेटाबेस कनेक्शन खोलना.
  • SQLiteConnection.prepare() का इस्तेमाल करके, एसक्यूएल स्टेटमेंट तैयार करना
  • SQLiteStatement को इस तरह से लागू करना:
    1. bind*() फ़ंक्शन का इस्तेमाल करके, ज़रूरत के हिसाब से आर्ग्युमेंट बाइंड करना.
    2. step() फ़ंक्शन का इस्तेमाल करके, नतीजों के सेट पर इटरेट करना.
    3. get*() फ़ंक्शन का इस्तेमाल करके, नतीजों के सेट से कॉलम पढ़ना.

ड्राइवर को लागू करने के तरीके

यहां दी गई टेबल में, ड्राइवर को लागू करने के उपलब्ध तरीकों की जानकारी दी गई है:

क्लास का नाम

सह-प्रॉडक्ट

इन प्लैटफ़ॉर्म पर काम करती हैं

AndroidSQLiteDriver androidx.sqlite:sqlite-framework

Android

NativeSQLiteDriver androidx.sqlite:sqlite-framework

iOS, Mac, और Linux

BundledSQLiteDriver androidx.sqlite:sqlite-bundled

Android, iOS, Mac, Linux, और जेवीएम (डेस्कटॉप)

androidx.sqlite:sqlite-bundled में उपलब्ध BundledSQLiteDriver को लागू करने का सुझाव दिया जाता है. इसमें, सोर्स से कंपाइल की गई SQLite लाइब्रेरी शामिल होती है. इससे, केएमपी के साथ काम करने वाले सभी प्लैटफ़ॉर्म पर, SQLite का सबसे नया वर्शन और एक जैसा अनुभव मिलता है.

SQLite ड्राइवर और Room

ड्राइवर एपीआई, SQLite डेटाबेस के साथ लो-लेवल इंटरैक्शन के लिए काम के होते हैं. अगर आपको ऐसी लाइब्रेरी चाहिए जिसमें कई सुविधाएं हों और SQLite को ज़्यादा अच्छे से ऐक्सेस किया जा सके, तो Room का इस्तेमाल करने का सुझाव दिया जाता है.

A RoomDatabase डेटाबेस की कार्रवाइयां करने के लिए SQLiteDriver पर निर्भर करता है. साथ ही, इसे कॉन्फ़िगर करने के लिए RoomDatabase.Builder.setDriver() का इस्तेमाल करना ज़रूरी है. Room, मैनेज किए गए डेटाबेस कनेक्शन को सीधे ऐक्सेस करने के लिए, RoomDatabase.useReaderConnection और RoomDatabase.useWriterConnection उपलब्ध कराता है.

Kotlin Multiplatform पर माइग्रेट करना

लो-लेवल सपोर्ट SQLite API कॉम्पोनेंट (जैसे, SupportSQLiteDatabase इंटरफ़ेस) के किसी भी इस्तेमाल को, SQLite ड्राइवर के मिलते-जुलते कॉम्पोनेंट पर माइग्रेट करना होगा.

Kotlin Multiplatform

लो-लेवल SQLiteConnection का इस्तेमाल करके लेन-देन करना

val connection: SQLiteConnection = ...
connection.execSQL("BEGIN IMMEDIATE TRANSACTION")
try {
  // perform database operations in transaction
  connection.execSQL("END TRANSACTION")
} catch(t: Throwable) {
  connection.execSQL("ROLLBACK TRANSACTION")
}

बिना किसी नतीजे के क्वेरी लागू करना

val connection: SQLiteConnection = ...
connection.execSQL("ALTER TABLE ...")

नतीजे के साथ क्वेरी लागू करना, लेकिन कोई आर्ग्युमेंट नहीं

val connection: SQLiteConnection = ...
connection.prepare("SELECT * FROM Pet").use { statement ->
  while (statement.step()) {
    // read columns
    statement.getInt(0)
    statement.getText(1)
  }
}

नतीजे और आर्ग्युमेंट के साथ क्वेरी लागू करना

connection.prepare("SELECT * FROM Pet WHERE id = ?").use { statement ->
  statement.bindInt(1, id)
  if (statement.step()) {
    // row found, read columns
  } else {
    // row not found
  }
}

सिर्फ़ Android के लिए

SupportSQLiteDatabase का इस्तेमाल करके लेन-देन करना

val database: SupportSQLiteDatabase = ...
database.beginTransaction()
try {
  // perform database operations in transaction
  database.setTransactionSuccessful()
} finally {
  database.endTransaction()
}

बिना किसी नतीजे के क्वेरी लागू करना

val database: SupportSQLiteDatabase = ...
database.execSQL("ALTER TABLE ...")

नतीजे के साथ क्वेरी लागू करना, लेकिन कोई आर्ग्युमेंट नहीं

val database: SupportSQLiteDatabase = ...
database.query("SELECT * FROM Pet").use { cursor ->
  while (cusor.moveToNext()) {
    // read columns
    cursor.getInt(0)
    cursor.getString(1)
  }
}

नतीजे और आर्ग्युमेंट के साथ क्वेरी लागू करना

database.query("SELECT * FROM Pet WHERE id = ?", id).use { cursor ->
  if (cursor.moveToNext()) {
    // row found, read columns
  } else {
    // row not found
  }
}