پایگاه داده اتاق خود را از قبل پر کنید

اگر می‌خواهید برنامه شما با پایگاه داده‌ای که از قبل با مجموعه‌ای خاص از داده‌ها بارگذاری شده است، شروع به کار کند، می‌توانید پایگاه داده را از قبل پر کنید. در Room، می‌توانید از APIها برای پر کردن اولیه یک پایگاه داده با محتویات یک فایل پایگاه داده از پیش بسته‌بندی شده در سیستم فایل دستگاه استفاده کنید.

از یک دارایی برنامه، پیش‌جمع‌آوری جمعیت انجام دهید

برای پر کردن اولیه پایگاه داده Room از یک فایل پایگاه داده از پیش بسته‌بندی شده که در هر جایی از پوشه assets/ برنامه شما قرار دارد، قبل از فراخوانی build تابع createFromAsset را از شیء RoomDatabase.Builder خود فراخوانی کنید:

Room.databaseBuilder<AppDatabase>(appContext, "sample.db")
    .createFromAsset("database/myapp.db")
    .build()

تابع createFromAsset یک آرگومان رشته‌ای را می‌پذیرد که شامل یک مسیر نسبی از دایرکتوری assets/ به فایل پایگاه داده از پیش بسته‌بندی شده است.

از سیستم فایل پیش-جمع‌آوری می‌کند

برای پر کردن اولیه پایگاه داده Room از یک فایل پایگاه داده از پیش بسته‌بندی شده که در هر جایی از سیستم فایل دستگاه به جز دایرکتوری assets/ برنامه شما قرار دارد، قبل از فراخوانی build تابع createFromFile را از شیء RoomDatabase.Builder خود فراخوانی کنید:

Room.databaseBuilder<AppDatabase>(appContext, "sample.db")
    .createFromFile(File("mypath"))
    .build()

تابع createFromFile یک آرگومان File برای فایل پایگاه داده از پیش بسته‌بندی شده می‌پذیرد. Room به جای باز کردن مستقیم فایل تعیین شده، یک کپی از آن ایجاد می‌کند، بنابراین مطمئن شوید که برنامه شما مجوزهای خواندن فایل را دارد.

مدیریت مهاجرت‌هایی که شامل پایگاه‌های داده از پیش بسته‌بندی‌شده هستند

فایل‌های پایگاه داده از پیش بسته‌بندی‌شده همچنین می‌توانند نحوه مدیریت مهاجرت‌های جایگزین توسط پایگاه داده Room شما را تغییر دهند. معمولاً، وقتی مهاجرت‌های مخرب فعال هستند و Room باید یک مهاجرت بدون مسیر مهاجرت انجام دهد، Room تمام جداول پایگاه داده را حذف می‌کند و یک پایگاه داده خالی با طرحواره مشخص شده برای نسخه هدف ایجاد می‌کند. با این حال، اگر یک فایل پایگاه داده از پیش بسته‌بندی‌شده با شماره مشابه نسخه هدف را اضافه کنید، Room پس از انجام مهاجرت مخرب، پایگاه داده تازه ایجاد شده را با محتویات فایل پایگاه داده از پیش بسته‌بندی‌شده پر می‌کند.

برای اطلاعات بیشتر در مورد مهاجرت پایگاه داده Room، به Migrate your Room database مراجعه کنید.

بخش‌های بعدی چند مثال از نحوه‌ی عملکرد این روش در عمل ارائه می‌دهند.

مثال: مهاجرت پشتیبان با یک پایگاه داده از پیش بسته‌بندی شده

فرض کنید موارد زیر:

  • برنامه شما یک پایگاه داده Room را در نسخه ۳ تعریف می‌کند.
  • نمونه پایگاه داده‌ای که از قبل روی دستگاه نصب شده است، نسخه ۲ است.
  • یک فایل پایگاه داده از پیش بسته‌بندی شده وجود دارد که روی نسخه ۳ است.
  • هیچ مسیر مهاجرت پیاده‌سازی‌شده‌ای از نسخه ۲ به نسخه ۳ وجود ندارد.
  • مهاجرت‌های مخرب فعال می‌شوند.

// 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()
}

در این شرایط چه اتفاقی می‌افتد:

  1. از آنجا که پایگاه داده تعریف شده در برنامه شما روی نسخه ۳ است و نمونه پایگاه داده‌ای که از قبل روی دستگاه نصب شده است روی نسخه ۲ است، یک مهاجرت ضروری است.
  2. از آنجا که هیچ برنامه مهاجرتی از نسخه ۲ به نسخه ۳ پیاده‌سازی نشده است، این مهاجرت یک مهاجرت جایگزین است.
  3. از آنجا که شما تابع سازنده‌ی fallbackToDestructiveMigration را فراخوانی می‌کنید، مهاجرت fallback مخرب است. Room نمونه‌ی پایگاه داده‌ای را که روی دستگاه نصب شده است، حذف می‌کند.
  4. از آنجا که یک فایل پایگاه داده از پیش بسته‌بندی شده روی نسخه ۳ وجود دارد، Room پایگاه داده را از نو ایجاد می‌کند و آن را با استفاده از محتویات فایل پایگاه داده از پیش بسته‌بندی شده پر می‌کند. اگر فایل پایگاه داده از پیش بسته‌بندی شده شما روی نسخه ۲ باشد، Room تشخیص می‌دهد که با نسخه هدف مطابقت ندارد و از آن برای مهاجرت پشتیبان استفاده نمی‌کند.

مثال: مهاجرت پیاده‌سازی شده با یک پایگاه داده از پیش بسته‌بندی شده

فرض کنید برنامه شما مسیر مهاجرت از نسخه ۲ به نسخه ۳ را پیاده‌سازی می‌کند:

// 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()
}

در این شرایط چه اتفاقی می‌افتد:

  1. از آنجا که پایگاه داده تعریف شده در برنامه شما روی نسخه ۳ است و پایگاه داده‌ای که از قبل روی دستگاه نصب شده روی نسخه ۲ است، یک مهاجرت ضروری است.
  2. از آنجا که یک مسیر مهاجرت پیاده‌سازی‌شده از نسخه ۲ به نسخه ۳ وجود دارد، Room تابع migrate تعریف‌شده را برای به‌روزرسانی نمونه پایگاه داده روی دستگاه به نسخه ۳ اجرا می‌کند و داده‌های موجود در پایگاه داده را حفظ می‌کند. Room از فایل پایگاه داده از پیش بسته‌بندی‌شده استفاده نمی‌کند، زیرا Room فقط در صورت مهاجرت مجدد از فایل‌های پایگاه داده از پیش بسته‌بندی‌شده استفاده می‌کند.

مثال: مهاجرت چند مرحله‌ای با یک پایگاه داده از پیش بسته‌بندی شده

فایل‌های پایگاه داده از پیش بسته‌بندی شده همچنین می‌توانند بر مهاجرت‌هایی که شامل چندین مرحله هستند تأثیر بگذارند. مورد زیر را در نظر بگیرید:

  • برنامه شما یک پایگاه داده Room را در نسخه ۴ تعریف می‌کند.
  • نمونه پایگاه داده‌ای که از قبل روی دستگاه نصب شده است، نسخه ۲ است.
  • یک فایل پایگاه داده از پیش بسته‌بندی شده وجود دارد که روی نسخه ۳ است.
  • یک مسیر مهاجرت پیاده‌سازی‌شده از نسخه ۳ به نسخه ۴ وجود دارد، اما از نسخه ۲ به نسخه ۳ خیر.
  • مهاجرت‌های مخرب فعال می‌شوند.

// 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()
}

در این شرایط چه اتفاقی می‌افتد:

  1. از آنجا که پایگاه داده تعریف شده در برنامه شما روی نسخه ۴ است و نمونه پایگاه داده‌ای که از قبل روی دستگاه نصب شده است روی نسخه ۲ است، یک مهاجرت ضروری است.
  2. از آنجا که هیچ مسیر مهاجرت پیاده‌سازی‌شده‌ای از نسخه ۲ به نسخه ۳ وجود ندارد، این مهاجرت یک مهاجرت بازگشتی است.
  3. از آنجا که شما تابع سازنده‌ی fallbackToDestructiveMigration را فراخوانی می‌کنید، مهاجرت fallback مخرب است. Room نمونه‌ی پایگاه داده را روی دستگاه حذف می‌کند.
  4. از آنجا که یک فایل پایگاه داده از پیش بسته‌بندی شده روی نسخه ۳ وجود دارد، Room پایگاه داده را از نو ایجاد می‌کند و آن را با استفاده از محتویات فایل پایگاه داده از پیش بسته‌بندی شده پر می‌کند.
  5. پایگاه داده نصب شده روی دستگاه اکنون نسخه ۳ است. از آنجا که هنوز از نسخه تعریف شده در برنامه شما پایین‌تر است، یک مهاجرت دیگر لازم است.
  6. از آنجا که یک مسیر مهاجرت پیاده‌سازی‌شده از نسخه ۳ به نسخه ۴ وجود دارد، Room تابع migrate تعریف‌شده را برای به‌روزرسانی نمونه پایگاه داده روی دستگاه به نسخه ۴ اجرا می‌کند و داده‌هایی را که از فایل پایگاه داده از پیش بسته‌بندی‌شده نسخه ۳ کپی شده بودند، حفظ می‌کند.