/*
* Copyright (C) 2012-2016 The Android Money Manager Ex Project Team
*
* 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, or (at your option) any later version.
*
* 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 com.money.manager.ex.database;
import android.content.Context;
import android.widget.Toast;
import com.money.manager.ex.R;
import com.money.manager.ex.home.MainActivity;
import com.money.manager.ex.settings.AppSettings;
import com.money.manager.ex.utils.MmxDatabaseUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import static com.money.manager.ex.Constants.DEFAULT_DB_FILENAME;
/**
* The code for migrating the databases used in v1.4 to use with 2.0.
* Users who do not use Dropbox have their databases in the old location. V2.0 started
* using the new location and many users report missing data.
*/
public class DatabaseMigrator14To20 {
public DatabaseMigrator14To20(Context context) {
mContext = context;
}
private Context mContext;
public Context getContext() {
return mContext;
}
/**
* Checks the legacy (v1.4) location for the database.
* @return boolean indicator whether there is a copy of database at the legacy location.
*/
public boolean legacyDataExists() {
String dbPath = getLegacyDbPath();
File legacyFile = new File(dbPath, DEFAULT_DB_FILENAME);
// Check if there is a file there.
// File dbFile = new File(dbPath);
// return dbFile.exists();
return legacyFile.exists();
}
/**
* Assembles the default db location for old version of the app.
* @return the legacy location of the database used with v1.4
*/
public String getLegacyDbPath() {
String dbPath;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {
dbPath = mContext.getApplicationInfo().dataDir;
} else {
dbPath = "/data/data/" + getContext().getApplicationContext().getPackageName();
}
// This was the default database name and it was impossible to create another one
// at this location.
dbPath += "/databases/" + DEFAULT_DB_FILENAME;
// dbPath += "/databases/";
// There are other internal databases, like webview.db, google_analytics, etc.
return dbPath;
}
public String getV20Directory() {
MmxDatabaseUtils dbUtils = new MmxDatabaseUtils(getContext());
File newPath = new File(dbUtils.getDefaultDatabaseDirectory());
String dbPath = newPath.toString();
return dbPath;
}
/**
* Copy the database from the old location (v1.4) into the new one (v2.0), set it as the
* default database, and start using.
* Does not check for existence. Use legacyDataExists() first.
* @return boolean indicator if the full operation was successful.
*/
public boolean migrateLegacyDatabase() {
boolean result = false;
String legacyPath = getLegacyDbPath();
File legacyFile = new File(legacyPath, DEFAULT_DB_FILENAME);
// copy the legacy database
String newPath = getV20Directory();
File newFile = new File(newPath, "legacyData.mmb");
try {
copy(legacyFile, newFile);
} catch (IOException e) {
e.printStackTrace();
return result;
}
// rename the legacy database to .bak
File backupFile = new File(legacyPath, "data.bak");
boolean renameSuccessful = legacyFile.renameTo(backupFile);
if (!renameSuccessful) return result;
// set the database path preference
AppSettings settings = new AppSettings(getContext());
String newFilename = newFile.toString();
settings.getDatabaseSettings().setDatabasePath(newFilename);
// open the newly copied database
// set to restart main activity to reload the db.
MainActivity.setRestartActivity(true);
Toast.makeText(getContext(), R.string.database_migrate_14_to_20_complete, Toast.LENGTH_LONG)
.show();
result = true;
return result;
}
public void copy(File src, File dst) throws IOException {
FileInputStream inStream = new FileInputStream(src);
FileOutputStream outStream = new FileOutputStream(dst);
FileChannel inChannel = inStream.getChannel();
FileChannel outChannel = outStream.getChannel();
inChannel.transferTo(0, inChannel.size(), outChannel);
inStream.close();
outStream.close();
}
}