I don't get any sense why they are writing two opposite variables in Logical OR. True || False = True, or False || True = True. Why this check is necessary?
if (mDatabase != null) {
if (!mDatabase.isOpen()) {
// Darn! The user closed the database by calling mDatabase.close().
mDatabase = null;
} else if (!writable || !mDatabase.isReadOnly()) {
// The database is already open for business.
return mDatabase;
}
}
Note: The same logic is applied in Samba file share also. There is a Samba explanation http://www.linuxtopia.org/online_books/network_administration_guides/using_samba_book/ch04_05_06.html
Can anyone clarify me here?
The code stub I presented above is in SQLiteOpenHelper class from line 222 to 231
Writable is defined by:
Note: Writable has nothing to do with your understanding here.
For the ReadOnly, there is a logic because ReadOnly is not opposite of Writable. This is where you are confused.
There are three things in ReadOnly: OPEN_READONLY, OPEN_READ_MASK, and OpenFlags.
Note: OPEN_READONLY is exactly opposite of Writable. This is where you were unclear.
Explanation OPEN_READ_MASK -- We set it to 1 (i.e. 0X00000001 in Hex) OPEN_READONLY -- We set it to 1 (i.e. 0X00000001 in Hex)
OpenFlags - Sometimes it is 1, sometimes it is 0. It is 1 if the disk not not full. It is 0 if the disk is full.
And, we calculate ReadOnly = (OpenFlags & OPEN_READ_MASK == OPEN_READONLY). Now, from this & operation, the ReadOnly always ensures even though the database is OPEN_READONLY, still it needs to satisfy it is not full. If it is full then ReadOnly becomes false.
That's why for every file and database, the above implemented & operation is reliable.
Proof:
If you ctrl+Alt click the method of isReadOnly(), you will see below lines of code.
public boolean isReadOnly() {
synchronized (mLock) {
return isReadOnlyLocked();
}
}
You further Ctrl+Alt+click on method isReadOnlyLocked(), you will see below lines of code.
private boolean isReadOnlyLocked() {
return (mConfigurationLocked.openFlags & OPEN_READ_MASK) == OPEN_READONLY;
}
You can see how OPEN_READ_MASK and OPEN_READONLY defined by further Ctrl+Alt+click, you see below lines of code.
/**
* Open flag: Flag for {@link #openDatabase} to open the database for reading only.
* This is the only reliable way to open a database if the disk may be full.
*/
public static final int OPEN_READONLY = 0x00000001; // update native code if changing
private static final int OPEN_READ_MASK = 0x00000001; // update native code if changing
If the disk is full, they system changes openFlags to 0 to ensure even though the disk is Openly readOnly still because of there is no disk space, you can't write. Now, I believe, you are clear.