how BoxStoreBuilder.usePreviousCommit works internally? - android

i converted my android app from mapdb to objectbox, i've seen on github a few people reporting database corruption with objectbox and the solution has always been to call usePreviousCommit in case of problems.
since the objectbox core is close source I wanted to know what usePreviousCommit does internally
are there 2 physical copies of the database? and calling usePreviousCommit reverts to the previous copy?
or does it work in a more complex way? (if yes i wanted to know how)
i opened this question because i want more information from objectbox before i continue to use it in production.

The key word is multiversion-concurrency. Think of a B+ tree with copy-on-write. The previous root tree (aka the previous commit) is preserved, so you can use when opening.

Related

Instrumentation Testing Room migrations

We have a project that extensively uses offline storage hence Room. The database has been migrated so many times that It is currently on V77.
we are planning to incorporate migration testing now ( I know it is too late ) hence want to write test for migration fron v77 to v78.
I wanted to know what is the best way to write tests for this scenario , The database is huge and complex containing joins etc.
I tried following the articles on Room migration tests but it is only for a small schema.
Also the Room generated schema jsons have been limited , would that be an issue for this ? and is there a way to generate the previous versions like 1.json etc.
I have followed the online medium articles precisely like it has been implemented and has been getting errors when migration happens on database joins etc.
Then I tried to follow the Android Doc for testing migrations but since I dont have the json files for pervious versions , I cannot implement that.
Can anyone suggest a good repo or already implemented tests for a similiar use case
Thanks .
and is there a way to generate the previous versions like 1.json etc.
yes, you can change the code for the previous version(s) so that in the #Database annotation exportSchema = true is coded AND that the room.schemaLocation is set accordingly (and obviously that the version number is set accordingly). You can the compile the project and the schema for that version will be generated.
Obviously due to the above changes the version being compiled is not exactly the same. However, the schema should be exactly as required as long as no other changes have been made that affect the schema.

Android -- Is SQLite deprecated or something? (Non-SDK warning spam)

so I made a basic application using the Room ORM to take care of my persistence (which uses SQLite). I'm a huge fan of SQLite myself, and am very familiar with it, such is why I chose room.
But every time I run my app, I get close to 1000 lines of warnings of "Accessing hidden field Landroid/database/sqlite/SQLiteDatabase;->.... " (the .... part is slightly different with every warning message).
From my understanding, that means I'm accessing non-sdk interfaces that may be removed in future versions without notice.
In which case, does that mean that SQLLite is deprecated in Android? I couldn't find any source online saying such a thing. But I really can't understand why else I'd be getting so many of these warnings.
Or is it just that Room is outdated? I tried with both android 11 and 10 and had the same problem.
I saw one other solution here which was to try and close the "Database Inspector" bundled with Android studio. Problem is: I'd like to use it, and every time I close it/remove from sidebar, it opens itself back up on the next run of my app.
Just wondering what the situation is here. Hopefully someone can help.
In which case, does that mean that SQLLite is deprecated in Android?
No.
Or is it just that Room is outdated?
No.
every time I run my app, I get close to 1000 lines of warnings of "Accessing hidden field Landroid/database/sqlite/SQLiteDatabase;->.... " (the .... part is slightly different with every warning message).
From my understanding, that means I'm accessing non-sdk interfaces that may be removed in future versions without notice.
Something — Room or Database Inspector, most likely, given your description — is using greylisted APIs. Room is created by Google. Database Inspector probably is created by Google (if not, it would be JetBrains). The decision of what hidden APIs get on the greylist is made by Google.
So, at some point, Google will need to talk to Google and decide what to do about Google's decision that affects Google's code. It is extraordinarily unlikely that some future version of Android will be released that somehow breaks Room and/or Database Inspector.
So, your focus for those warnings is whether you directly are using those hidden APIs. If you are not, then I would not spend much time worrying about it.

Android/JVM SQLite database

I'm trying to have a small Android app have its own database, my first take on this was to simply use the Room persistence library, and it worked wonders, it's an awesome library but...
Later on I decided to try something weird and port that app to Desktop too (JVM).
My plan was to have 3 gradle modules:
common logic
android (importing common)
jvm (importing common)
Problem is that... I can't use Room anymore since it would be in the common logic module that's not an android module.
I tried to switch to Ktorm, and it seemed nice but Ktorm can't create tables from the schema so i had to drop it.
Then i tried to switch to Exposed since it has the functionality to create tables from the schema, but Exposed has a few problems:
The JDBC driver for Desktop (xerial) is not supported on android, so i should use different drivers per platform (for example using SQLDroid for android)
Its DAO can't have a table with a composite key (which i need to have), and not having the DAO would make everything harder in the code since I'd have to issue the queries directly and get a ResultRow, and then convert them to the objects I need.
My last resort would be creating some monstruous class that totally hide the database providing only the minimum read and write methods that i need and has some sort of flag called android and totally change what its methods do if that flag is true or false, so that it would use Room on Android and Exposed on JVM, but it sounds like a terrible idea.
Some idea of how would it be possible to create and use a simple SQLite database in both JVM and Android with the same code?
UPDATE:
I'm now using SQLDelight and even though it's not as comfy as Room and its documentation isn't super extensive, it's pretty nice and does what i wanted, figured out writing this could be useful for someone that come across my same doubt.

Android Room: Replace existing schema (migrations and all) with a new one?

I've been messing around with an Android project that uses a room database. Because I didn't design the database before I started (I didn't initially plan to even use one), it has a bunch of migrations that drop and recreate tables all over again.
I've never released the app since it's kind of a learning project, but if I ever show anyone I'd rather not show them the 3 migrations in a row where I drop and recreate the table. Is there a way just to tell it to use a completely new schema, as if it had never used one before?
Turns out I hadn't been wording my Google searches properly. I should have searched for how to reset to version 1 since that's a lot clearer than dropping tables or schemas.
See this stackoverflow link below to see what answered my question:
Room persistent library reset version to 1

onUpgrade race condition in running app

we are using ormlite successfully in our android application; for maintaining database versions, we use an approach like here:
http://www.michenux.net/android-database-sqlite-creation-upgrade-245.html
Lately, we've seen "paranormal activity" in the field with apps being in databases states they could not "sanely be", and are trying to find explanations.
One could be that, when a running App is upgraded automatically by Google Play, the onUpgrade() is executed, changing tables and data, while the old (or the new?) App, or maybe their IntentServices concurrently access the database, and get strange results.
(Sadly, there is no easy way to just say "completely stop my app before upgrade, do the upgrade, then completely restart". There is the MY_PACKAGE_REPLACED intent, but opinions on how to use it greatly vary...)
So my question is, is there any safeguard in place that will make onUpgrade() run exclusively, i.e. blocking or locking or synchronizing anything, to make sure another thread does not access my table while I e.g. drop a column (i.e. rename, recreate, copy over data from old tab).
If no, how could I achieve such a thing in the safest way ?
Thanks & kind regards.
Okay, so -
the thorough analysis exposed another (handmade) issue (in our code) that caused all those problems.
So, not to spread any rumours: It seems there is no race condition in onUpgrade() !
It would have been nice to know if it is good practice to have an (exclusive?) transaction block for onUpgrade(), though...
I do have one migration using begin transaction, und sqlite throws an error upon nested transactions, so I am pretty sure there is none around onUpgrade() automatically.
For clarification on other issues
Yes, Apps are terminated before being upgraded.
Only Services might need to re-read config, and alarms (timers) might need restarting.

Categories

Resources