codenameone / CodenameOne

Cross-platform framework for building truly native mobile apps with Java or Kotlin. Write Once Run Anywhere support for iOS, Android, Desktop & Web.
https://www.codenameone.com/
Other
1.7k stars 402 forks source link

RFE: [Android] Expose some methods for transaction sqlite #2040

Open JrmyDev opened 7 years ago

JrmyDev commented 7 years ago

Actually, we can begin a transaction sqlite with "beginTransaction" method. Other methods such as "beginTransactionNonExclusive" are not available.

I would like to begin a non exclusive transaction (see https://www.sqlite.org/lang_transaction.html) but I can't. By default, transaction sqlite are deferred.

I already try to execute query "BEGIN" to begin a simple transaction but log in android studio tell me that it execute "BEGIN EXCLUSIVE" because the core of android sqlite library reinterpret String in query (see https://github.com/iosphere/sqlite-android/blob/master/library/src/main/java/org/sqlite/database/sqlite/SQLiteSession.java and calls to executeSpecial(...)method).

I suggest you to expose methods of SQLiteDatabase class like beginTransactionNonExclusive().

FYI, I'm currently locked on my project because transaction on android doesn't work as expected (in contrary of iOS which work great).

Thanks,

Jérémy.

codenameone commented 7 years ago

Shouldn't this be the other way around?

Shouldn't we just map transactions on Android to use beginTransactionNonExclusive() instead of beginTransaction() so it will be consistent with iOS/simulator instead of introducing a new API?

JrmyDev commented 7 years ago

If you mean invoke SQLiteDatabase.beginTransactionNonExclusive(...) in AndroidDB.beginTransaction() method, I don't think it's a good idea because it will be inconsistent with sqlite core api of Android.

Actually, I misunderstood android sqlite api core because it's not coherent with SQLite documentation. I mean, SQLiteDatabase.beginTransaction() method should lead to deferred transaction which is default in sqlite. Bigger problem is that Android SQLite API wrap every SQL query, that we would like to execute, with SQLiteSession.executeSpecial(...) method which prevent us to execute simple query as BEGIN; (not BEGIN EXCLUSIVE;).

In CodenameOne API side, we are blocked because there is not every method of SQLite API (both Android and iOS). Having access to method public void beginTransaction(int transactionMode, SQLiteTransactionListener transactionListener, int connectionFlags, CancellationSignal cancellationSignal) of SQLiteSession would be the best case.

codenameone commented 7 years ago

Is that method available in both underlying platforms?

What would you do for a platform that doesn't support it e.g. JavaScript?

Maybe the right thing to do is to invoke that method with consistent arguments both on iOS, Android & JavaSE so all 3 behave the same?

JrmyDev commented 7 years ago

There is no method available to begin a transaction in iOS.

For a platform like JavaScript, we could put a log message similar to beginTransaction one :

System.out.println("** Database.beginTransaction() is not supported in the Javascript port. If you plan to deploy to Javascript, you should avoid this method. ***");

Yes, we could also add 3 constant like SQLiteSession Android API :

public static final int TRANSACTION_MODE_DEFERRED = 0;
public static final int TRANSACTION_MODE_IMMEDIATE = 1;
public static final int TRANSACTION_MODE_EXCLUSIVE = 2; 

and add this as parameter : beginTransaction(int TransactionMode)

JrmyDev commented 7 years ago

Could you implement this ? I would like to do it, but if so, I will not be able to debug modified native android sources (because I'm using Eclipse ...)

codenameone commented 7 years ago

Sorry I was a bit busy and this got pushed back. I'm still not sure this is the right approach. I'm not sure if inconsistency with Android is a bad thing. I'd rather have the android/simulator/iOS/javascript consistent than the API being consistent with the rest of Android. The suggestion above would add a new API that's only applicable for Android and that's a bad direction.

JrmyDev commented 7 years ago

In your last comment, you said :

Maybe the right thing to do is to invoke that method with consistent arguments both on iOS, Android & JavaSE so all 3 behave the same?

I have answered you that I agree and we could based our implementation on Android API. If we do that, we will have android/simulator/iOS/javascript consistent. It means it won't break old usage of beginTransaction() method and it will offer to user possibility to use the different SQLite transactions (this is not possible currently on Android, we can only do exclusive transaction).

To answer your last sentence, add this new API will be applicable for Android/simulator/iOS (and for javascript, it will be the same as beginTransaction()).