/******************************************************************************* * 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; } }