package com.truckmuncher.app.data.sql;
import android.content.Context;
import android.content.res.Resources;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.support.annotation.NonNull;
import android.support.annotation.RawRes;
import com.truckmuncher.app.R;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import timber.log.Timber;
public abstract class SqlOpenHelper extends SQLiteOpenHelper {
public static final int VERSION = 2;
private final Context context;
protected SqlOpenHelper(Context context, String dbName, int version) {
super(context, dbName, null, version);
this.context = context.getApplicationContext();
}
public static SqlOpenHelper newInstance(Context context) {
return new SqlOpenHelperImpl(context);
}
@Override
public final void onCreate(@NonNull SQLiteDatabase db) {
// Create structure
readAndExecuteSQLScript(db, context, R.raw.truckmuncher);
// Apply any migration found. This way we don't have to rewrite the original and lose out history
onUpgrade(db, 1, VERSION);
}
@Override
public final void onUpgrade(@NonNull SQLiteDatabase db, int oldVersion, int newVersion) {
for (int i = oldVersion; i < newVersion; ++i) {
String migrationFileName = String.format("from_%d_to_%d", i, (i + 1));
Timber.d("Looking for migration file: %s", migrationFileName);
int migrationFileResId = context.getResources().getIdentifier(migrationFileName, "raw", context.getPackageName());
if (migrationFileResId != 0) {
// execute script
readAndExecuteSQLScript(db, context, migrationFileResId);
} else {
Timber.d("Not found: %s", migrationFileName);
}
}
}
private void readAndExecuteSQLScript(SQLiteDatabase db, Context context, @RawRes int sqlScriptResId) {
Resources res = context.getResources();
try {
InputStream is = res.openRawResource(sqlScriptResId);
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
executeSQLScript(db, reader);
reader.close();
is.close();
} catch (IOException e) {
throw new RuntimeException("Unable to read SQL script", e);
}
}
private void executeSQLScript(SQLiteDatabase db, BufferedReader reader) throws IOException {
String line;
StringBuilder statement = new StringBuilder();
while ((line = reader.readLine()) != null) {
statement.append(line);
statement.append("\n");
if (line.endsWith(";")) {
String toExec = statement.toString();
Timber.d("Executing script: \n%s", toExec);
db.execSQL(toExec);
statement = new StringBuilder();
}
}
}
private static class SqlOpenHelperImpl extends SqlOpenHelper {
private static final String NAME = "truckmuncher.db";
private SqlOpenHelperImpl(Context context) {
super(context, NAME, VERSION);
}
}
}