/*******************************************************************************
* Copyright (c) 2011 Michel DAVID mimah35-at-gmail.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
package fr.gotorennes.persistence;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.URL;
import java.util.zip.GZIPInputStream;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteQueryBuilder;
import android.util.Log;
import fr.gotorennes.R;
public class BusDatabase {
private static final String TAG = "GoToRennes.BusDatabase";
private SQLiteDatabase dataBase;
private final Context context;
public BusDatabase(Context context) {
this.context = context;
}
public synchronized void initOrUpdate(final ProgressDialog progress, boolean forceUpdate) {
Log.i(TAG, "Initialisation de la base de données");
if (progress != null) {
if (progress.getOwnerActivity() != null) {
progress.getOwnerActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
progress.setMessage(context.getString(R.string.checkDatabase));
}
});
}
int version = getCurrentVersion();
if ((version != 0 && needUpdate(version)) || forceUpdate) {
if (progress.getOwnerActivity() != null) {
progress.getOwnerActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
progress.setMessage(context.getString(R.string.updateDatabase));
}
});
}
close();
copy();
open();
updateVersion(version);
}
else {
open();
}
}
else {
open();
}
}
protected int getCurrentVersion() {
try {
String stringVersion = new BufferedReader(new InputStreamReader(new URL("https://raw.githubusercontent.com/mimah/Go2Rennes-utils/master/data/version.txt").openStream())).readLine();
return Integer.parseInt(stringVersion);
}
catch (Exception ex) {
Log.e(TAG, "Error while checking available version " + ex.getMessage());
}
return 0;
}
protected boolean needUpdate(int version) {
return !exists() || dataBase.getVersion() != version;
}
protected boolean exists() {
try {
open();
} catch (SQLiteException e) {
Log.d(TAG, "La base de données n'existe pas");
}
return dataBase != null;
}
protected void copy() {
Log.i(TAG, "Copie de la base de données");
GZIPInputStream myGzipInput = null;
OutputStream myOutput = null;
try {
InputStream myInput = new URL("https://raw.githubusercontent.com/mimah/Go2Rennes-utils/master/data/bus.zip").openStream();
myGzipInput = new GZIPInputStream(myInput);
myOutput = context.openFileOutput("bus.db", Context.MODE_PRIVATE);
byte[] buffer = new byte[1024];
int length;
while ((length = myGzipInput.read(buffer)) > 0) {
myOutput.write(buffer, 0, length);
}
} catch (IOException e) {
Log.e(TAG, "Téléchargement de la base de données impossible", e);
throw new Error("Téléchargement de la base de données impossible.\n" + e.getMessage(), e);
} finally {
try {
if (myOutput != null) {
myOutput.flush();
myOutput.close();
}
if (myGzipInput != null) {
myGzipInput.close();
}
} catch (IOException e) {
}
}
}
protected void updateVersion(int version) {
Log.i(TAG, "Mise à jour de la version de la base de données");
dataBase.setVersion(version);
Log.i(TAG, "Création des index");
dataBase.execSQL("CREATE INDEX IF NOT EXISTS ID1 ON STATION_CIRCUIT (idStation)");
dataBase.execSQL("CREATE INDEX IF NOT EXISTS ID2 ON ARRET (idStation)");
dataBase.execSQL("CREATE INDEX IF NOT EXISTS ID3 ON TRAJET (idCircuit)");
dataBase.execSQL("CREATE INDEX IF NOT EXISTS ID4 ON STATION_CIRCUIT (idCircuit)");
dataBase.execSQL("CREATE INDEX IF NOT EXISTS ID5 ON ARRET (idTrajet)");
dataBase.execSQL("CREATE INDEX IF NOT EXISTS ID6 ON ARRET (idStation, idTrajet)");
SharedPreferences prefs = context.getSharedPreferences("fr.gotorennes.Application", 0);
prefs.edit().putString("gtfs", String.valueOf(version)).commit();
}
protected void open() {
Log.i(TAG, "Ouverture de la base de données");
dataBase = SQLiteDatabase.openDatabase(context.getFileStreamPath("bus.db").getAbsolutePath(), null, SQLiteDatabase.OPEN_READWRITE);
}
public synchronized void close() {
if (dataBase != null) {
Log.i(TAG, "Fermeture de la base de données");
dataBase.close();
}
}
public Cursor query(String tables, String[] projections, String selection, String[] selectionArgs, String sort, String limit) {
SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
builder.setTables(tables);
Cursor cursor = builder.query(dataBase, projections, selection, selectionArgs, null, null, sort, limit);
if (cursor == null) {
return null;
} else if (!cursor.moveToFirst()) {
cursor.close();
return null;
}
return cursor;
}
public Cursor query(String sql, String[] selectionArgs) {
Cursor cursor = dataBase.rawQuery(sql, selectionArgs);
if (cursor == null) {
return null;
}
if (!cursor.moveToFirst()) {
cursor.close();
return null;
}
return cursor;
}
}