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.support.annotation.NonNull;
import android.support.annotation.WorkerThread;
import android.util.SparseArray;
import com.quran.labs.androidquran.common.LocalTranslation;
import com.quran.labs.androidquran.dao.translation.TranslationItem;
import com.quran.labs.androidquran.util.QuranFileUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Singleton;
import timber.log.Timber;
import static com.quran.labs.androidquran.database.TranslationsDBHelper.TranslationsTable;
@Singleton
public class TranslationsDBAdapter {
private final Context context;
private final SQLiteDatabase db;
private volatile List<LocalTranslation> cachedTranslations;
@Inject
public TranslationsDBAdapter(Context context, TranslationsDBHelper adapter) {
this.context = context;
this.db = adapter.getWritableDatabase();
}
public SparseArray<LocalTranslation> getTranslationsHash() {
List<LocalTranslation> items = getTranslations();
SparseArray<LocalTranslation> result = new SparseArray<>();
for (int i = 0, itemsSize = items.size(); i < itemsSize; i++) {
LocalTranslation item = items.get(i);
result.put(item.id, item);
}
return result;
}
@WorkerThread
@NonNull
public List<LocalTranslation> getTranslations() {
// intentional, since cachedTranslations can be replaced by another thread, causing the check
// to be true, but the cached object returned to be null (or to change).
List<LocalTranslation> cached = cachedTranslations;
if (cached != null && cached.size() > 0) {
return cached;
}
List<LocalTranslation> items = new ArrayList<>();
Cursor cursor = db.query(TranslationsTable.TABLE_NAME,
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);
if (QuranFileUtils.hasTranslation(context, filename)) {
items.add(new LocalTranslation(id, filename, name, translator,
translatorForeign, url, languageCode, version));
}
}
cursor.close();
}
items = Collections.unmodifiableList(items);
if (items.size() > 0) {
cachedTranslations = items;
}
return items;
}
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()) {
ContentValues values = new ContentValues();
values.put(TranslationsTable.ID, item.translation.id);
values.put(TranslationsTable.NAME, item.translation.displayName);
values.put(TranslationsTable.TRANSLATOR, item.translation.translator);
values.put(TranslationsTable.TRANSLATOR_FOREIGN,
item.translation.translatorNameLocalized);
values.put(TranslationsTable.FILENAME, item.translation.fileName);
values.put(TranslationsTable.URL, item.translation.fileUrl);
values.put(TranslationsTable.LANGUAGE_CODE, item.translation.languageCode);
values.put(TranslationsTable.VERSION, item.localVersion);
db.replace(TranslationsTable.TABLE_NAME, null, values);
} else {
db.delete(TranslationsTable.TABLE_NAME,
TranslationsTable.ID + " = " + item.translation.id, null);
}
}
db.setTransactionSuccessful();
// clear the cached translations
this.cachedTranslations = null;
} catch (Exception e) {
result = false;
Timber.d(e, "error writing translation updates");
} finally {
db.endTransaction();
}
return result;
}
}