-
Notifications
You must be signed in to change notification settings - Fork 894
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support Reordering Of Translations. Fixes #1179 #1398
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package com.quran.labs.androidquran.common | ||
|
||
class LocalTranslationDisplaySort : Comparator<LocalTranslation> { | ||
override fun compare(p0: LocalTranslation, p1: LocalTranslation): Int { | ||
return p0.displayOrder.compareTo(p1.displayOrder); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package com.quran.labs.androidquran.dao.translation | ||
|
||
class TranslationItemDisplaySort : Comparator<TranslationItem> { | ||
override fun compare(p0: TranslationItem, p1: TranslationItem): Int { | ||
return p0.displayOrder.compareTo(p1.displayOrder); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -72,23 +72,27 @@ public List<LocalTranslation> getTranslations() { | |
null, null, null, null, null, | ||
TranslationsTable.ID + " ASC"); | ||
if (cursor != null) { | ||
while (cursor.moveToNext()) { | ||
int id = cursor.getInt(0); | ||
String name = cursor.getString(1); | ||
String translator = cursor.getString(2); | ||
String translatorForeign = cursor.getString(3); | ||
String filename = cursor.getString(4); | ||
String url = cursor.getString(5); | ||
String languageCode = cursor.getString(6); | ||
int version = cursor.getInt(7); | ||
int minimumVersion = cursor.getInt(8); | ||
|
||
if (quranFileUtils.hasTranslation(context, filename)) { | ||
items.add(new LocalTranslation(id, filename, name, translator, | ||
translatorForeign, url, languageCode, version, minimumVersion)); | ||
try { | ||
while (cursor.moveToNext()) { | ||
int id = cursor.getInt(0); | ||
String name = cursor.getString(1); | ||
String translator = cursor.getString(2); | ||
String translatorForeign = cursor.getString(3); | ||
String filename = cursor.getString(4); | ||
String url = cursor.getString(5); | ||
String languageCode = cursor.getString(6); | ||
int version = cursor.getInt(7); | ||
int minimumVersion = cursor.getInt(8); | ||
int displayOrder = cursor.getInt(9); | ||
|
||
if (quranFileUtils.hasTranslation(context, filename)) { | ||
items.add(new LocalTranslation(id, filename, name, translator, | ||
translatorForeign, url, languageCode, version, minimumVersion, displayOrder)); | ||
} | ||
} | ||
} finally { | ||
cursor.close(); | ||
} | ||
cursor.close(); | ||
} | ||
items = Collections.unmodifiableList(items); | ||
if (items.size() > 0) { | ||
|
@@ -105,11 +109,35 @@ public void deleteTranslationByFile(String filename) { | |
public boolean writeTranslationUpdates(List<TranslationItem> updates) { | ||
boolean result = true; | ||
db.beginTransaction(); | ||
|
||
try { | ||
for (int i = 0, updatesSize = updates.size(); i < updatesSize; i++) { | ||
TranslationItem item = updates.get(i); | ||
if (item.exists()) { | ||
int displayOrder = 0; | ||
|
||
final Translation translation = item.getTranslation(); | ||
|
||
if (item.getDisplayOrder() > -1) { | ||
displayOrder = item.getDisplayOrder(); | ||
} else { | ||
// get next highest display order | ||
Cursor cursor = db.query( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please, consider closing this cursor. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. oops, yes to both cursor comments There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you should do this in a try / finally because if an exception is thrown due to the query, we will leak the cursor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sorry to nitpick, the try/catch should be before the cursor assignment even - so like: Cursor cursor = null;
try {
cursor = ..
} finally {
DatabasUtils.closeCursor(cursor);
} |
||
TranslationsTable.TABLE_NAME, | ||
new String[] {TranslationsTable.DISPLAY_ORDER}, | ||
null, null, null, null, | ||
TranslationsTable.DISPLAY_ORDER + " DESC", | ||
"1" | ||
); | ||
try { | ||
if (cursor != null && cursor.moveToFirst()) { | ||
displayOrder = cursor.getInt(0) + 1; | ||
} | ||
} finally { | ||
if (cursor !=null) cursor.close(); | ||
} | ||
} | ||
|
||
ContentValues values = new ContentValues(); | ||
values.put(TranslationsTable.ID, translation.getId()); | ||
values.put(TranslationsTable.NAME, translation.getDisplayName()); | ||
|
@@ -121,6 +149,7 @@ public boolean writeTranslationUpdates(List<TranslationItem> updates) { | |
values.put(TranslationsTable.LANGUAGE_CODE, translation.getLanguageCode()); | ||
values.put(TranslationsTable.VERSION, item.getLocalVersion()); | ||
values.put(TranslationsTable.MINIMUM_REQUIRED_VERSION, translation.getMinimumVersion()); | ||
values.put(TranslationsTable.DISPLAY_ORDER, displayOrder); | ||
|
||
db.replace(TranslationsTable.TABLE_NAME, null, values); | ||
} else { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,8 @@ | ||
package com.quran.labs.androidquran.database; | ||
|
||
import android.content.ContentValues; | ||
import android.content.Context; | ||
import android.database.Cursor; | ||
import android.database.sqlite.SQLiteDatabase; | ||
import android.database.sqlite.SQLiteOpenHelper; | ||
|
||
|
@@ -11,7 +13,7 @@ | |
class TranslationsDBHelper extends SQLiteOpenHelper { | ||
|
||
private static final String DB_NAME = "translations.db"; | ||
private static final int DB_VERSION = 4; | ||
private static final int DB_VERSION = 5; | ||
private static final String CREATE_TRANSLATIONS_TABLE = | ||
"CREATE TABLE " + TranslationsTable.TABLE_NAME + "(" + | ||
TranslationsTable.ID + " integer primary key, " + | ||
|
@@ -22,7 +24,9 @@ class TranslationsDBHelper extends SQLiteOpenHelper { | |
TranslationsTable.URL + " varchar, " + | ||
TranslationsTable.LANGUAGE_CODE + " varchar, " + | ||
TranslationsTable.VERSION + " integer not null default 0," + | ||
TranslationsTable.MINIMUM_REQUIRED_VERSION + " integer not null default 0);"; | ||
TranslationsTable.MINIMUM_REQUIRED_VERSION + " integer not null default 0, " + | ||
TranslationsTable.DISPLAY_ORDER + " integer not null default -1 " + | ||
");"; | ||
|
||
@Inject | ||
TranslationsDBHelper(Context context) { | ||
|
@@ -69,6 +73,41 @@ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { | |
db.endTransaction(); | ||
} | ||
} | ||
if (oldVersion < 5) { | ||
// Add display order column and add arbitrary order to existing translations | ||
db.beginTransaction(); | ||
try { | ||
db.execSQL("ALTER TABLE " | ||
+ TranslationsTable.TABLE_NAME | ||
+ " ADD COLUMN " | ||
+ TranslationsTable.DISPLAY_ORDER | ||
+ " integer not null default -1" | ||
); | ||
Cursor translations = db.query( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am not entirely sure if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. +1 - also, as a hack, can we just use the row id as the value here so we don't have to do an upload loop? UPDATE translations SET display_order = id |
||
TranslationsTable.TABLE_NAME, new String[] { TranslationsTable.ID }, null, null, null, null, null | ||
); | ||
try { | ||
if (translations != null && translations.moveToFirst()) { | ||
for (int i = 0; i < translations.getCount(); i++) { | ||
ContentValues values = new ContentValues(); | ||
values.put(TranslationsTable.DISPLAY_ORDER, i); | ||
db.update( | ||
TranslationsTable.TABLE_NAME, | ||
values, | ||
TranslationsTable.ID + " = ?", | ||
new String[] { String.valueOf(translations.getInt(0)) } | ||
); | ||
translations.moveToNext(); | ||
} | ||
} | ||
} finally { | ||
if (translations != null) translations.close(); | ||
} | ||
db.setTransactionSuccessful(); | ||
} finally { | ||
db.endTransaction(); | ||
} | ||
} | ||
} | ||
|
||
static class TranslationsTable { | ||
|
@@ -82,5 +121,6 @@ static class TranslationsTable { | |
static final String LANGUAGE_CODE = "languageCode"; | ||
static final String VERSION = "version"; | ||
static final String MINIMUM_REQUIRED_VERSION = "minimumRequiredVersion"; | ||
static final String DISPLAY_ORDER = "userDisplayOrder"; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see comment below - try should move up though
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Salam, @ahmedre, can you explain why would we need to close a
null
cursor?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wa3laikum alsalam - you don't, but you can't skip closing the cursor until you assign it either - so as a better pattern, you do something like:
cursor.close()
can actually throw also, which is why we have theDatabaseUtils.closeCursor
method which does that for you - it checks if it's null and if so does nothing - if it's not null, it tries to close it and swallows any exceptions it throws.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, ok, @ahmedre, you just shuffled the null check, lol. I can't say that is necessarily "better"... actually it's a little more "traditional" e.g. to catch errors from cursor instantiation, in which case you'd need to keep a reference to it outside of try/catch. But that's neither here nor there.
However, I'm curious about
DatabaseUtils.closeCursor
. Why would we want to swallowcursor.close()
and notdb.query()
. I was going for consistency (ie throw everything)... but are you just wanting to ignore cursor close errors specifically?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if
cursor.close()
fails, there's nothing i can do about it - there's nothing that can be fixed, etc so we swallow it.db.query()
failing could be because of a bad query, missing column, etc and can fail for a number of reasons, and in all of these cases i want to know about it so i can fix it.