अगर आपको अपने ऐप्लिकेशन को ऐसे डेटाबेस के साथ शुरू करना है जिसमें पहले से ही डेटा का कोई खास सेट लोड है, तो डेटाबेस में पहले से डेटा लोड किया जा सकता है. Room में, एपीआई का इस्तेमाल करके, डिवाइस के फ़ाइल सिस्टम में मौजूद पहले से पैक किए गए डेटाबेस फ़ाइल के कॉन्टेंट से, डेटाबेस को शुरू में ही लोड किया जा सकता है.
ऐप्लिकेशन ऐसेट से पहले से डेटा लोड करना
Room डेटाबेस में पहले से डेटा लोड करने के लिए, पहले से पैक किए गए डेटाबेस की फ़ाइल का इस्तेमाल किया जा सकता है. यह फ़ाइल, आपके ऐप्लिकेशन की
assets/ डायरेक्ट्री में कहीं भी हो सकती है. इसके लिए, build को कॉल करने से पहले, अपने RoomDatabase.Builder ऑब्जेक्ट से createFromAsset
फ़ंक्शन को कॉल करें:
Room.databaseBuilder<AppDatabase>(appContext, "sample.db") .createFromAsset("database/myapp.db") .build()
createFromAsset फ़ंक्शन, एक स्ट्रिंग आर्ग्युमेंट स्वीकार करता है. इसमें assets/ डायरेक्ट्री से, पहले से पैक किए गए डेटाबेस की फ़ाइल तक का रिलेटिव पाथ होता है.
फ़ाइल सिस्टम से पहले से डेटा लोड करना
Room डेटाबेस में पहले से डेटा लोड करने के लिए, पहले से पैक किए गए डेटाबेस की फ़ाइल का इस्तेमाल किया जा सकता है. यह फ़ाइल, डिवाइस के फ़ाइल सिस्टम में कहीं भी हो सकती है.
हालांकि, यह आपके ऐप्लिकेशन की assets/ डायरेक्ट्री में नहीं होनी चाहिए.
इसके लिए, build को कॉल करने से पहले, अपने RoomDatabase.Builder
ऑब्जेक्ट से createFromFile फ़ंक्शन को कॉल करें:
Room.databaseBuilder<AppDatabase>(appContext, "sample.db") .createFromFile(File("mypath")) .build()
createFromFile फ़ंक्शन, पहले से पैक किए गए डेटाबेस की फ़ाइल के लिए, File आर्ग्युमेंट स्वीकार करता है. Room, तय की गई फ़ाइल को सीधे तौर पर खोलने के बजाय, उसकी एक कॉपी बनाता है. इसलिए, पक्का करें कि आपके ऐप्लिकेशन के पास फ़ाइल को पढ़ने की अनुमति हो.
पहले से पैक किए गए डेटाबेस वाले माइग्रेशन को मैनेज करना
पहले से पैक किए गए डेटाबेस की फ़ाइलें, Room डेटाबेस में फ़ॉलबैक माइग्रेशन को मैनेज करने के तरीके में भी बदलाव कर सकती हैं. आम तौर पर, जब डिस्ट्रक्टिव माइग्रेशन की सुविधा चालू होती है और Room को माइग्रेशन पाथ के बिना माइग्रेशन करना होता है, तो Room डेटाबेस में मौजूद सभी टेबल को हटा देता है. साथ ही, टारगेट वर्शन के लिए तय किए गए स्कीमा के साथ एक खाली डेटाबेस बनाता है . हालांकि, अगर आपने पहले से पैक किए गए डेटाबेस की कोई ऐसी फ़ाइल शामिल की है जिसका नंबर, टारगेट वर्शन के नंबर के बराबर है, तो Room, डिस्ट्रक्टिव माइग्रेशन करने के बाद, नए तरीके से बनाए गए डेटाबेस में, पहले से पैक किए गए डेटाबेस की फ़ाइल का कॉन्टेंट लोड कर देता है.
Room डेटाबेस के माइग्रेशन के बारे में ज़्यादा जानने के लिए, Room डेटाबेस को माइग्रेट करना लेख पढ़ें.
यहां कुछ उदाहरण दिए गए हैं, जिनसे पता चलता है कि यह सुविधा कैसे काम करती है.
उदाहरण: पहले से पैक किए गए डेटाबेस के साथ फ़ॉलबैक माइग्रेशन
मान लें कि:
- आपका ऐप्लिकेशन, वर्शन 3 पर Room डेटाबेस को तय करता है.
- डिवाइस पर पहले से इंस्टॉल किया गया डेटाबेस इंस्टेंस, वर्शन 2 पर है.
- पहले से पैक किए गए डेटाबेस की एक फ़ाइल है, जो वर्शन 3 पर है.
- वर्शन 2 से वर्शन 3 पर माइग्रेट करने के लिए, कोई पाथ लागू नहीं किया गया है.
- डिस्ट्रक्टिव माइग्रेशन की सुविधा चालू है.
// Database class definition declaring version 3. @Database(entities = [SampleEntity::class], version = 3) abstract class FallbackAppDatabase : RoomDatabase() { // ... } fun createFallbackDb(appContext: Context) { Room.databaseBuilder<FallbackAppDatabase>(appContext, "sample.db") .createFromAsset("database/myapp.db") .fallbackToDestructiveMigration() .build() }
इस स्थिति में, यह होता है:
- आपके ऐप्लिकेशन में तय किया गया डेटाबेस, वर्शन 3 पर है. वहीं, डिवाइस पर पहले से इंस्टॉल किया गया डेटाबेस इंस्टेंस, वर्शन 2 पर है. इसलिए, माइग्रेशन करना ज़रूरी है.
- वर्शन 2 से वर्शन 3 पर माइग्रेट करने के लिए, कोई प्लान लागू नहीं किया गया है. इसलिए, यह माइग्रेशन, फ़ॉलबैक माइग्रेशन है.
- आपने
fallbackToDestructiveMigrationबिल्डर फ़ंक्शन को कॉल किया है. इसलिए, फ़ॉलबैक माइग्रेशन, डिस्ट्रक्टिव माइग्रेशन है. Room, डिवाइस पर इंस्टॉल किए गए डेटाबेस इंस्टेंस को हटा देता है. - पहले से पैक किए गए डेटाबेस की एक फ़ाइल है, जो वर्शन 3 पर है. इसलिए, Room डेटाबेस को फिर से बनाता है और उसमें, पहले से पैक किए गए डेटाबेस की फ़ाइल का कॉन्टेंट लोड कर देता है. अगर पहले से पैक किए गए डेटाबेस की फ़ाइल, वर्शन 2 पर है, तो Room यह तय करता है कि यह टारगेट वर्शन से मेल नहीं खाती. इसलिए, Room, फ़ॉलबैक माइग्रेशन के लिए इसका इस्तेमाल नहीं करता.
उदाहरण: पहले से पैक किए गए डेटाबेस के साथ लागू किया गया माइग्रेशन
इसके बजाय, मान लें कि आपका ऐप्लिकेशन, वर्शन 2 से वर्शन 3 पर माइग्रेट करने के लिए, कोई पाथ लागू करता है:
// Database class definition declaring version 3. @Database(entities = [SampleEntity::class], version = 3) abstract class ImplementedAppDatabase : RoomDatabase() { // ... } // Migration path definition from version 2 to version 3. val MIGRATION_2_3 = object : Migration(2, 3) { override suspend fun migrate(connection: SQLiteConnection) { // ... } } fun createImplementedDb(appContext: Context) { Room.databaseBuilder<ImplementedAppDatabase>(appContext, "sample.db") .createFromAsset("database/myapp.db") .addMigrations(MIGRATION_2_3) .build() }
इस स्थिति में, यह होता है:
- आपके ऐप्लिकेशन में तय किया गया डेटाबेस, वर्शन 3 पर है. वहीं, डिवाइस पर पहले से इंस्टॉल किया गया डेटाबेस, वर्शन 2 पर है. इसलिए, माइग्रेशन करना ज़रूरी है.
- वर्शन 2 से वर्शन 3 पर माइग्रेट करने के लिए, कोई पाथ लागू किया गया है.
इसलिए, Room, तय किए गए
migrateफ़ंक्शन को चलाकर, डिवाइस पर मौजूद डेटाबेस इंस्टेंस को वर्शन 3 पर अपडेट करता है. साथ ही, डेटाबेस में पहले से मौजूद डेटा को सेव रखता है. Room, पहले से पैक किए गए डेटाबेस की फ़ाइल का इस्तेमाल नहीं करता, क्योंकि Room, पहले से पैक किए गए डेटाबेस की फ़ाइलों का इस्तेमाल सिर्फ़ फ़ॉलबैक माइग्रेशन के मामले में करता है.
उदाहरण: पहले से पैक किए गए डेटाबेस के साथ, कई चरणों वाला माइग्रेशन
पहले से पैक किए गए डेटाबेस की फ़ाइलें, कई चरणों वाले माइग्रेशन को भी प्रभावित कर सकती हैं. यहां एक उदाहरण दिया गया है:
- आपका ऐप्लिकेशन, वर्शन 4 पर Room डेटाबेस को तय करता है.
- डिवाइस पर पहले से इंस्टॉल किया गया डेटाबेस इंस्टेंस, वर्शन 2 पर है.
- पहले से पैक किए गए डेटाबेस की एक फ़ाइल है, जो वर्शन 3 पर है.
- वर्शन 3 से वर्शन 4 पर माइग्रेट करने के लिए, कोई पाथ लागू किया गया है. हालांकि, वर्शन 2 से वर्शन 3 पर माइग्रेट करने के लिए, कोई पाथ लागू नहीं किया गया है.
- डिस्ट्रक्टिव माइग्रेशन की सुविधा चालू है.
// Database class definition declaring version 4. @Database(entities = [SampleEntity::class], version = 4) abstract class MultiStepAppDatabase : RoomDatabase() { // ... } val MIGRATION_3_4 = object : Migration(3, 4) { override suspend fun migrate(connection: SQLiteConnection) { // ... } } fun createMultiStepDb(appContext: Context) { Room.databaseBuilder<MultiStepAppDatabase>(appContext, "sample.db") .createFromAsset("database/myapp.db") .addMigrations(MIGRATION_3_4) .fallbackToDestructiveMigration() .build() }
इस स्थिति में, यह होता है:
- आपके ऐप्लिकेशन में तय किया गया डेटाबेस, वर्शन 4 पर है. वहीं, डिवाइस पर पहले से इंस्टॉल किया गया डेटाबेस इंस्टेंस, वर्शन 2 पर है. इसलिए, माइग्रेशन करना ज़रूरी है.
- वर्शन 2 से वर्शन 3 पर माइग्रेट करने के लिए, कोई पाथ लागू नहीं किया गया है. इसलिए, यह माइग्रेशन, फ़ॉलबैक माइग्रेशन है.
- आपने
fallbackToDestructiveMigrationबिल्डर फ़ंक्शन को कॉल किया है. इसलिए, फ़ॉलबैक माइग्रेशन, डिस्ट्रक्टिव माइग्रेशन है. Room, डिवाइस पर मौजूद डेटाबेस इंस्टेंस को हटा देता है. - पहले से पैक किए गए डेटाबेस की एक फ़ाइल है, जो वर्शन 3 पर है. इसलिए, Room डेटाबेस को फिर से बनाता है और उसमें, पहले से पैक किए गए डेटाबेस की फ़ाइल का कॉन्टेंट लोड कर देता है.
- डिवाइस पर इंस्टॉल किया गया डेटाबेस अब वर्शन 3 पर है. यह अब भी आपके ऐप्लिकेशन में तय किए गए वर्शन से कम है. इसलिए, एक और माइग्रेशन करना ज़रूरी है.
- वर्शन 3 से वर्शन 4 पर माइग्रेट करने के लिए, कोई पाथ लागू किया गया है.
इसलिए, Room, तय किए गए
migrateफ़ंक्शन को चलाकर, डिवाइस पर मौजूद डेटाबेस इंस्टेंस को वर्शन 4 पर अपडेट करता है. साथ ही, वर्शन 3 के पहले से पैक किए गए डेटाबेस की फ़ाइल से कॉपी किए गए डेटा को सेव रखता है.