Merge pull request #3831 from ByteHamster/verify-database
Verify database version before import
This commit is contained in:
commit
3f85413b8d
|
@ -216,8 +216,8 @@ public class ImportExportPreferencesFragment extends PreferenceFragmentCompat {
|
|||
|
||||
private void showExportErrorDialog(final Throwable error) {
|
||||
progressDialog.dismiss();
|
||||
final AlertDialog.Builder alert = new AlertDialog.Builder(getContext())
|
||||
.setNeutralButton(android.R.string.ok, (dialog, which) -> dialog.dismiss());
|
||||
final AlertDialog.Builder alert = new AlertDialog.Builder(getContext());
|
||||
alert.setPositiveButton(android.R.string.ok, (dialog, which) -> dialog.dismiss());
|
||||
alert.setTitle(R.string.export_error_label);
|
||||
alert.setMessage(error.getMessage());
|
||||
alert.show();
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package de.danoeh.antennapod.core.storage;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteException;
|
||||
import android.net.Uri;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.util.Log;
|
||||
|
@ -14,21 +16,10 @@ import java.io.FileOutputStream;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class DatabaseExporter {
|
||||
private static final String TAG = "DatabaseExporter";
|
||||
private static final byte[] SQLITE3_MAGIC = "SQLite format 3\0".getBytes();
|
||||
|
||||
public static boolean validateDB(Uri inputUri, Context context) throws IOException {
|
||||
try (InputStream inputStream = context.getContentResolver().openInputStream(inputUri)) {
|
||||
byte[] magicBuf = new byte[SQLITE3_MAGIC.length];
|
||||
if (inputStream.read(magicBuf) == magicBuf.length) {
|
||||
return Arrays.equals(SQLITE3_MAGIC, magicBuf);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
private static final String TEMP_DB_NAME = PodDBAdapter.DATABASE_NAME + "_tmp";
|
||||
|
||||
public static void exportToDocument(Uri uri, Context context) throws IOException {
|
||||
ParcelFileDescriptor pfd = null;
|
||||
|
@ -78,14 +69,21 @@ public class DatabaseExporter {
|
|||
public static void importBackup(Uri inputUri, Context context) throws IOException {
|
||||
InputStream inputStream = null;
|
||||
try {
|
||||
if (!validateDB(inputUri, context)) {
|
||||
throw new IOException(context.getString(R.string.import_bad_file));
|
||||
File tempDB = context.getDatabasePath(TEMP_DB_NAME);
|
||||
inputStream = context.getContentResolver().openInputStream(inputUri);
|
||||
FileUtils.copyInputStreamToFile(inputStream, tempDB);
|
||||
|
||||
SQLiteDatabase db = SQLiteDatabase.openDatabase(tempDB.getAbsolutePath(),
|
||||
null, SQLiteDatabase.OPEN_READONLY);
|
||||
if (db.getVersion() > PodDBAdapter.VERSION) {
|
||||
throw new IOException(context.getString(R.string.import_no_downgrade));
|
||||
}
|
||||
db.close();
|
||||
|
||||
File currentDB = context.getDatabasePath(PodDBAdapter.DATABASE_NAME);
|
||||
inputStream = context.getContentResolver().openInputStream(inputUri);
|
||||
FileUtils.copyInputStreamToFile(inputStream, currentDB);
|
||||
} catch (IOException e) {
|
||||
currentDB.delete();
|
||||
FileUtils.moveFile(tempDB, currentDB);
|
||||
} catch (IOException | SQLiteException e) {
|
||||
Log.e(TAG, Log.getStackTraceString(e));
|
||||
throw e;
|
||||
} finally {
|
||||
|
|
|
@ -48,6 +48,7 @@ public class PodDBAdapter {
|
|||
|
||||
private static final String TAG = "PodDBAdapter";
|
||||
public static final String DATABASE_NAME = "Antennapod.db";
|
||||
public static final int VERSION = 1090000;
|
||||
|
||||
/**
|
||||
* Maximum number of arguments for IN-operator.
|
||||
|
@ -1336,8 +1337,6 @@ public class PodDBAdapter {
|
|||
* Helper class for opening the Antennapod database.
|
||||
*/
|
||||
private static class PodDBHelper extends SQLiteOpenHelper {
|
||||
private static final int VERSION = 1090000;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
|
@ -1345,8 +1344,7 @@ public class PodDBAdapter {
|
|||
* @param name Name of the database
|
||||
* @param factory to use for creating cursor objects
|
||||
*/
|
||||
public PodDBHelper(final Context context, final String name,
|
||||
final CursorFactory factory) {
|
||||
public PodDBHelper(final Context context, final String name, final CursorFactory factory) {
|
||||
super(context, name, factory, VERSION, new PodDbErrorHandler());
|
||||
}
|
||||
|
||||
|
@ -1369,10 +1367,8 @@ public class PodDBAdapter {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onUpgrade(final SQLiteDatabase db, final int oldVersion,
|
||||
final int newVersion) {
|
||||
Log.w("DBAdapter", "Upgrading from version " + oldVersion + " to "
|
||||
+ newVersion + ".");
|
||||
public void onUpgrade(final SQLiteDatabase db, final int oldVersion, final int newVersion) {
|
||||
Log.w("DBAdapter", "Upgrading from version " + oldVersion + " to " + newVersion + ".");
|
||||
DBUpgrader.upgrade(db, oldVersion, newVersion);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -572,6 +572,7 @@
|
|||
<string name="opml_import_ask_read_permission">Access to external storage is required to read the OPML file</string>
|
||||
<string name="import_select_file">Select file to import</string>
|
||||
<string name="import_ok">Import successful.\n\nPlease press OK to restart AntennaPod</string>
|
||||
<string name="import_no_downgrade">This database was exported with a newer version of AntennaPod. Your current installation does not yet know how to handle this file.</string>
|
||||
|
||||
<!-- Sleep timer -->
|
||||
<string name="set_sleeptimer_label">Set sleep timer</string>
|
||||
|
@ -768,7 +769,6 @@
|
|||
<string name="cast_failed_to_play">Failed to start the playback of media</string>
|
||||
<string name="cast_failed_to_stop">Failed to stop the playback of media</string>
|
||||
<string name="cast_failed_to_pause">Failed to pause the playback of media</string>
|
||||
<!--<string name="cast_failed_to_connect">Could not connect to the device</string>-->
|
||||
<string name="cast_failed_setting_volume">Failed to set the volume</string>
|
||||
<string name="cast_failed_no_connection">No connection to the cast device is present</string>
|
||||
<string name="cast_failed_no_connection_trans">Connection to the cast device has been lost. Application is trying to re-establish the connection, if possible. Please wait for a few seconds and try again.</string>
|
||||
|
@ -786,7 +786,6 @@
|
|||
<string name="notification_channel_playing_description">Allows to control playback. This is the main notification you see while playing a podcast.</string>
|
||||
<string name="notification_channel_error">Errors</string>
|
||||
<string name="notification_channel_error_description">Shown if something went wrong, for example if download or gpodder sync fails.</string>
|
||||
<string name="import_bad_file">Invalid/corrupt file</string>
|
||||
|
||||
<!-- Widget settings -->
|
||||
<string name="widget_settings">Widget settings</string>
|
||||
|
|
Loading…
Reference in New Issue