package org.wikipedia.history;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.support.annotation.NonNull;
import org.wikipedia.database.DatabaseTable;
import org.wikipedia.database.column.Column;
import org.wikipedia.database.contract.PageHistoryContract;
import org.wikipedia.database.contract.PageHistoryContract.Col;
import org.wikipedia.dataclient.WikiSite;
import org.wikipedia.page.PageTitle;
import org.wikipedia.util.log.L;
import java.util.Date;
public class HistoryEntryDatabaseTable extends DatabaseTable<HistoryEntry> {
private static final int DB_VER_NAMESPACE_ADDED = 6;
private static final int DB_VER_NORMALIZED_TITLES = 8;
private static final int DB_VER_LANG_ADDED = 10;
private static final int DB_VER_TIME_SPENT_ADDED = 15;
public HistoryEntryDatabaseTable() {
super(PageHistoryContract.TABLE, PageHistoryContract.Page.URI);
}
@Override
public HistoryEntry fromCursor(Cursor cursor) {
WikiSite wiki = new WikiSite(Col.SITE.val(cursor), Col.LANG.val(cursor));
PageTitle title = new PageTitle(Col.NAMESPACE.val(cursor), Col.TITLE.val(cursor), wiki);
Date timestamp = Col.TIMESTAMP.val(cursor);
int source = Col.SOURCE.val(cursor);
return new HistoryEntry(title, timestamp, source);
}
@Override
protected ContentValues toContentValues(HistoryEntry obj) {
ContentValues contentValues = new ContentValues();
contentValues.put(Col.SITE.getName(), obj.getTitle().getWikiSite().authority());
contentValues.put(Col.LANG.getName(), obj.getTitle().getWikiSite().languageCode());
contentValues.put(Col.TITLE.getName(), obj.getTitle().getText());
contentValues.put(Col.NAMESPACE.getName(), obj.getTitle().getNamespace());
contentValues.put(Col.TIMESTAMP.getName(), obj.getTimestamp().getTime());
contentValues.put(Col.SOURCE.getName(), obj.getSource());
contentValues.put(Col.TIME_SPENT.getName(), obj.getTimeSpentSec());
return contentValues;
}
@NonNull
@Override
public Column<?>[] getColumnsAdded(int version) {
switch (version) {
case INITIAL_DB_VERSION:
return new Column<?>[] {Col.ID, Col.SITE, Col.TITLE, Col.TIMESTAMP, Col.SOURCE};
case DB_VER_NAMESPACE_ADDED:
return new Column<?>[] {Col.NAMESPACE};
case DB_VER_LANG_ADDED:
return new Column<?>[] {Col.LANG};
case DB_VER_TIME_SPENT_ADDED:
return new Column<?>[] {Col.TIME_SPENT};
default:
return super.getColumnsAdded(version);
}
}
@Override
protected String getPrimaryKeySelection(@NonNull HistoryEntry obj,
@NonNull String[] selectionArgs) {
return super.getPrimaryKeySelection(obj, PageHistoryContract.Col.SELECTION);
}
@Override
protected String[] getUnfilteredPrimaryKeySelectionArgs(@NonNull HistoryEntry obj) {
return new String[] {
obj.getTitle().getWikiSite().authority(),
obj.getTitle().getWikiSite().languageCode(),
obj.getTitle().getNamespace(),
obj.getTitle().getText()
};
}
@Override
protected int getDBVersionIntroducedAt() {
return INITIAL_DB_VERSION;
}
@Override
protected void upgradeSchema(@NonNull SQLiteDatabase db, int toVersion) {
switch (toVersion) {
case DB_VER_NORMALIZED_TITLES:
convertAllTitlesToUnderscores(db);
break;
case DB_VER_LANG_ADDED:
addLangToAllSites(db);
break;
default:
super.upgradeSchema(db, toVersion);
}
}
/**
* One-time fix for the inconsistencies in title formats all over the database. This migration will enforce
* all titles stored in the database to follow the "Underscore_format" instead of the "Human readable form"
* TODO: Delete this code after April 2016
*
* @param db Database object
*/
private void convertAllTitlesToUnderscores(SQLiteDatabase db) {
Cursor cursor = db.query(getTableName(), null, null, null, null, null, null);
ContentValues values = new ContentValues();
while (cursor.moveToNext()) {
String title = Col.TITLE.val(cursor);
if (title.contains(" ")) {
values.put(Col.TITLE.getName(), title.replace(" ", "_"));
String id = Long.toString(Col.ID.val(cursor));
db.updateWithOnConflict(getTableName(), values, Col.ID.getName() + " = ?",
new String[]{id}, SQLiteDatabase.CONFLICT_REPLACE);
}
}
cursor.close();
}
// TODO: remove in September 2016.
private void addLangToAllSites(@NonNull SQLiteDatabase db) {
L.i("Adding language codes to " + getTableName());
Cursor cursor = db.query(getTableName(), null, null, null, null, null, null);
try {
while (cursor.moveToNext()) {
String site = Col.SITE.val(cursor);
ContentValues values = new ContentValues();
values.put(Col.LANG.getName(), site.split("\\.")[0]);
String id = Long.toString(Col.ID.val(cursor));
db.updateWithOnConflict(getTableName(), values, Col.ID.getName() + " = ?",
new String[]{id}, SQLiteDatabase.CONFLICT_REPLACE);
}
} finally {
cursor.close();
}
}
}