Как импортировать существующую базу данных SQLite3 в Room? - PullRequest
0 голосов
/ 30 июня 2018

Хорошо, поэтому я использовал SQLite3 на рабочем столе для создания базы данных определенной информации, которую нужно только прочитать. Приложение, которое я создаю, не требует вставки или удаления информации из этой таблицы.

Я довольно много погуглил на уровне базы данных Room, и вся документация влечет за собой создание новой базы данных в Room, пока ваше приложение создается - что-то мне не нужно, поскольку у меня уже есть такая.

Как бы я мог, чтобы Room читал уже существующую базу данных? Моя база данных в настоящее время хранится в /app/src/main/assets/splitbilldatabase.db.

1 Ответ

0 голосов
/ 30 июня 2018

Первое, что вам нужно сделать, это создать все для схемы Room, готовой для импорта (@Database, @ Entity для таблиц и т. Д.), Которая должна точно соответствовать схеме базы данных, которая будет импортирован.

Файл внешней базы данных должен быть скопирован (как у вас) в папку ресурсов.

Затем вы можете скопировать файл перед любой попыткой открыть базу данных Room, например, в методе RoomDatabase init, но , только если файл / база данных еще не существует .

Ниже приведен рабочий (но не всесторонне протестированный) пример: -

@Database(entities = {MyTable.class,
        MyOthertable.class,
        MyMappingTable.class},version = 1,
        exportSchema = false)

public abstract class  MyDatabase extends RoomDatabase {

    public static final String DBNAME = "splitbilldatabase.db";


    public static final String TB_MYTABLE = "mytable";
    public static final String TB_MYOTHERTABLE = "myothertable";
    public static final String TB_MYMAPPINGTABLE = "mymappingtable";

    public static final String COL_MYTABLE_ID = BaseColumns._ID;
    public static final String COL_MYTABLE_NAME = "_name";
    public static final String COL_MYTABLE_DESCRIPTION = "_description";

    public static final String COL_MYOTHERTABLE_ID = BaseColumns._ID;
    public static final String COL_MYOTHERTABLE_OTHERDETAILS = "_otherdetails";

    public static  final String COL_MYMAPPINGTABLE_MYTABLEREFERENCE = "_mytable_reference";
    public static final String COL_MYMAPPINGTABLE_MYOTEHERTABLEREFERENCE = "_myothertable_reference";

    public abstract MyTableDao myTableDao();
    public abstract MyOtherTableDao myOtherTableDao();
    public abstract MyMappingTableDao myMappingTableDao();

    public MyDatabase() {
        super();
    }

    @Override
    public void init(@NonNull DatabaseConfiguration configuration) {
        importExistingDatabase(configuration.context, true); //<<<<<<<<<< Invokes the Import of the Exisiting Database.
        super.init(configuration);
    }

    private void importExistingDatabase(Context context, boolean throw_exception) {
        int buffer_size = 32768;
        File dbpath = context.getDatabasePath(DBNAME);
        if (dbpath.exists()) {
            return; // Database already exists
        }
        // Just in case make the directories
        File dirs = new File(dbpath.getParent());
        dirs.mkdirs();
        int stage = 0;
        byte[] buffer = new byte[buffer_size];
        long total_bytes_read = 0;
        long total_bytes_written = 0;
        int bytes_read = 0;
        try {  
            InputStream assetdb = context.getAssets().open(DBNAME);
            stage++;
            dbpath.createNewFile();
            stage++;
            OutputStream realdb = new FileOutputStream(dbpath);
            stage++;
            while((bytes_read = assetdb.read(buffer)) > 0) {
                total_bytes_read = total_bytes_read + bytes_read;
                realdb.write(buffer,0,bytes_read);
                total_bytes_written = total_bytes_written + bytes_read;
            }
            stage++;
            realdb.flush();
            stage++;
            assetdb.close();
            stage++;
            realdb.close();
            stage++;
        } catch (IOException e) {
            String failed_at = "";
            switch  (stage) {
                case 0:
                    failed_at = "Opening Asset " + DBNAME;
                    break;
                case 1:
                    failed_at = "Creating Output Database " + dbpath.getAbsolutePath();
                    break;
                case 2:
                    failed_at = "Genreating Database OutputStream " + dbpath.getAbsolutePath();
                    break;
                case 3:
                    failed_at = "Copying Data from Asset Database to Output Database. " +
                            " Bytes read=" + String.valueOf(total_bytes_read) +
                            " Bytes written=" + String.valueOf(total_bytes_written);
                    break;
                case 4:
                    failed_at = "Flushing Written Data (" +
                            String.valueOf(total_bytes_written) +
                            " bytes written)";
                    break;
                case 5:
                    failed_at = "Closing Asset Database File.";
                    break;
                case 6:
                    failed_at = "Closing Created Database File.";
            }
            String msg = "An error was encountered copying the Database " +
                    "from the asset file to New Database. " +
                    "The error was encountered whilst :-\n\t" + failed_at;
            Log.e("IMPORTDATABASE",msg);
            e.printStackTrace();
            if (throw_exception) {
                throw new RuntimeException(msg);
            }
        }
    }
}
  • Обратите внимание, что предполагается, что имена файлов совпадают.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...