From bbabe7a311feea8584cee4aa347fd1769841b85d Mon Sep 17 00:00:00 2001 From: Tonyo Francis Date: Thu, 19 Apr 2018 08:53:43 -0400 Subject: [PATCH] updated fetch migrator --- CHANGELOG | 3 ++ README.md | 10 ++--- .../tonyodev/fetchmigrator/FetchMigrator.kt | 41 ++++++++++++++----- .../fetchmigrator/fetch1/DatabaseHelper.kt | 3 +- .../fetch1/DownloadTransferPair.kt | 5 +++ .../fetchmigrator/fetch1/ErrorUtils.kt | 20 ++++----- .../fetchmigrator/fetch1/FetchConst.kt | 20 ++++----- .../fetchmigrator/helpers/TypeConverters.kt | 9 ++-- versions.gradle | 4 +- 9 files changed, 74 insertions(+), 41 deletions(-) create mode 100644 fetchmigrator/src/main/java/com/tonyodev/fetchmigrator/fetch1/DownloadTransferPair.kt diff --git a/CHANGELOG b/CHANGELOG index 17df4863..65bac09a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,6 @@ +Version 2.0.0-RC15 +- updated Fetch Migrator + Version 2.0.0-RC14 - Bug fixes to database sanitize methods diff --git a/README.md b/README.md index 47768681..cb6e1183 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ [![Build Status](https://travis-ci.org/tonyofrancis/Fetch.svg?branch=v2)](https://travis-ci.org/tonyofrancis/Fetch) -[ ![Download](https://api.bintray.com/packages/tonyofrancis/maven/fetch2/images/download.svg?version=2.0.0-RC14) ](https://bintray.com/tonyofrancis/maven/fetch2/2.0.0-RC14/link) +[ ![Download](https://api.bintray.com/packages/tonyofrancis/maven/fetch2/images/download.svg?version=2.0.0-RC15) ](https://bintray.com/tonyofrancis/maven/fetch2/2.0.0-RC15/link) [![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-Android%20Networking-blue.svg?style=flat)](https://android-arsenal.com/details/1/5196) [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](https://github.com/tonyofrancis/Fetch/blob/master/LICENSE) @@ -45,7 +45,7 @@ How to use Fetch Using Fetch is easy! Just add the Gradle dependency to your application's build.gradle file. ```java -implementation "com.tonyodev.fetch2:fetch2:2.0.0-RC14" +implementation "com.tonyodev.fetch2:fetch2:2.0.0-RC15" ``` Next, get an instance of Fetch using the builder, and request a download. @@ -244,7 +244,7 @@ to use the OkHttp Downloader instead. You can create your own custom downloaders if necessary. See the Java docs for details. ```java -implementation "com.tonyodev.fetch2downloaders:fetch2downloaders:2.0.0-RC14" +implementation "com.tonyodev.fetch2downloaders:fetch2downloaders:2.0.0-RC15" ``` Set the OkHttp Downloader for Fetch to use. ```java @@ -265,7 +265,7 @@ If you would like to take advantage of RxJava2 features when using Fetch, add the following gradle dependency to your application's build.gradle file. ```java -implementation "com.tonyodev.fetch2rx:fetch2rx:2.0.0-RC14" +implementation "com.tonyodev.fetch2rx:fetch2rx:2.0.0-RC15" ``` RxFetch makes it super easy to enqueue download requests and query downloads using rxJava2 functional methods. @@ -297,7 +297,7 @@ Fetch1 Migration Migrate downloads from Fetch1 to Fetch2 using the migration assistant. Add the following gradle dependency to your application's build.gradle file. ```java -implementation "com.tonyodev.fetchmigrator:fetchmigrator:2.0.0-RC14" +implementation "com.tonyodev.fetchmigrator:fetchmigrator:2.0.0-RC15" ``` Then run the Migrator. diff --git a/fetchmigrator/src/main/java/com/tonyodev/fetchmigrator/FetchMigrator.kt b/fetchmigrator/src/main/java/com/tonyodev/fetchmigrator/FetchMigrator.kt index e9c3ba96..432bf9be 100644 --- a/fetchmigrator/src/main/java/com/tonyodev/fetchmigrator/FetchMigrator.kt +++ b/fetchmigrator/src/main/java/com/tonyodev/fetchmigrator/FetchMigrator.kt @@ -10,33 +10,52 @@ import com.tonyodev.fetch2.database.DatabaseManagerImpl import com.tonyodev.fetch2.database.DownloadDatabase import com.tonyodev.fetch2.database.DownloadInfo import com.tonyodev.fetchmigrator.fetch1.DatabaseHelper +import com.tonyodev.fetchmigrator.fetch1.DownloadTransferPair import com.tonyodev.fetchmigrator.helpers.v1CursorToV2DownloadInfo import java.io.File import java.io.IOException import java.sql.SQLException +/** Migrates Downloads from Fetch version 1 to Fetch version 2. Note that the ids + * of the transferred downloads will be different in version 2. See the list DownloadTransferPair + * returned by this method. Note that this method must be called on a background thread or else + * an SQLiteException error will be thrown. + * + * @param context context + * @param v2Namespace Fetch 2 namespace that the downloads from version 1 will be transferred to. + * + * @return list of transferred downloads(DownloadTransferPair). Each download transfer pair includes the newDownload + * object used in Fetch version 2. downloadTransferPair.getNewDownload().getId() is + * the new id for the download in Fetch version 2. downloadTransferPair.getOldID() + * is the id for the download in Fetch version 1. Update your external references + * accordingly. + * + * @throws SQLException - If there is an issue opening or getting data from a database. + * @throws SQLiteConstraintException - If a download in the v2 namespace already has a matching id. This + * error will most likely be thrown when trying to insert a download from v1 that was already transferred to + * v2. + * */ @WorkerThread @Throws(exceptionClasses = [SQLException::class, SQLiteConstraintException::class]) -fun migrateFromV1toV2(context: Context, v2Namespace: String): List { +fun migrateFromV1toV2(context: Context, v2Namespace: String): List { val fetchOneDatabaseHelper = DatabaseHelper(context) fetchOneDatabaseHelper.clean() fetchOneDatabaseHelper.verifyOK() - val downloadInfoList = mutableListOf() + val downloadInfoList = mutableListOf() val cursor = fetchOneDatabaseHelper.get() if (cursor != null) { cursor.moveToFirst() while (!cursor.isAfterLast) { - val downloadInfo = v1CursorToV2DownloadInfo(cursor) + val downloadTransferPair = v1CursorToV2DownloadInfo(cursor) try { - val file = File(downloadInfo.file) + val file = File(downloadTransferPair.newDownload.file) if (file.exists()) { - downloadInfo.downloaded = file.length() + (downloadTransferPair.newDownload as DownloadInfo).downloaded = file.length() } } catch (e: IOException) { - } - downloadInfo.namespace = v2Namespace - downloadInfoList.add(downloadInfo) + (downloadTransferPair.newDownload as DownloadInfo).namespace = v2Namespace + downloadInfoList.add(downloadTransferPair) cursor.moveToNext() } cursor.close() @@ -46,14 +65,16 @@ fun migrateFromV1toV2(context: Context, v2Namespace: String): List { isMemoryDatabase = false, logger = FetchLogger(), migrations = DownloadDatabase.getMigrations()) - - fetchTwoDatabaseManager.insert(downloadInfoList) + fetchTwoDatabaseManager.insert(downloadInfoList.map { it.newDownload as DownloadInfo }) fetchTwoDatabaseManager.close() } fetchOneDatabaseHelper.close() return downloadInfoList } +/** Deletes the database for Fetch version 1 + * @param context + * */ fun deleteFetchV1Database(context: Context) { context.deleteDatabase(DatabaseHelper.DB_NAME) } diff --git a/fetchmigrator/src/main/java/com/tonyodev/fetchmigrator/fetch1/DatabaseHelper.kt b/fetchmigrator/src/main/java/com/tonyodev/fetchmigrator/fetch1/DatabaseHelper.kt index 84491702..46455c58 100644 --- a/fetchmigrator/src/main/java/com/tonyodev/fetchmigrator/fetch1/DatabaseHelper.kt +++ b/fetchmigrator/src/main/java/com/tonyodev/fetchmigrator/fetch1/DatabaseHelper.kt @@ -40,7 +40,7 @@ internal class DatabaseHelper constructor(context: Context) fun get(): Cursor? { synchronized(lock) { - return db.rawQuery("SELECT * FROM " + TABLE_NAME, null) + return db.rawQuery("SELECT * FROM $TABLE_NAME", null) } } @@ -99,6 +99,7 @@ internal class DatabaseHelper constructor(context: Context) const val COLUMN_FILE_SIZE = "_file_size" const val COLUMN_ERROR = "_error" const val COLUMN_PRIORITY = "_priority" + const val INDEX_ID = 0 const val INDEX_COLUMN_URL = 1 const val INDEX_COLUMN_FILEPATH = 2 const val INDEX_COLUMN_STATUS = 3 diff --git a/fetchmigrator/src/main/java/com/tonyodev/fetchmigrator/fetch1/DownloadTransferPair.kt b/fetchmigrator/src/main/java/com/tonyodev/fetchmigrator/fetch1/DownloadTransferPair.kt new file mode 100644 index 00000000..1780f8ec --- /dev/null +++ b/fetchmigrator/src/main/java/com/tonyodev/fetchmigrator/fetch1/DownloadTransferPair.kt @@ -0,0 +1,5 @@ +package com.tonyodev.fetchmigrator.fetch1 + +import com.tonyodev.fetch2.Download + +data class DownloadTransferPair(val newDownload: Download, val oldID: Long) \ No newline at end of file diff --git a/fetchmigrator/src/main/java/com/tonyodev/fetchmigrator/fetch1/ErrorUtils.kt b/fetchmigrator/src/main/java/com/tonyodev/fetchmigrator/fetch1/ErrorUtils.kt index d5d7576e..b130c371 100644 --- a/fetchmigrator/src/main/java/com/tonyodev/fetchmigrator/fetch1/ErrorUtils.kt +++ b/fetchmigrator/src/main/java/com/tonyodev/fetchmigrator/fetch1/ErrorUtils.kt @@ -1,14 +1,14 @@ package com.tonyodev.fetchmigrator.fetch1 internal object ErrorUtils { - val FILE_NOT_CREATED = -102 - val CONNECTION_TIMED_OUT = -104 - val UNKNOWN_HOST = -105 - val HTTP_NOT_FOUND = -106 - val WRITE_PERMISSION_DENIED = -107 - val N0_STORAGE_SPACE = -108 - val SERVER_ERROR = -110 - val FILE_NOT_FOUND = -111 - val REQUEST_ALREADY_EXIST = -113 - val ENQUEUE_ERROR = -117 + const val FILE_NOT_CREATED = -102 + const val CONNECTION_TIMED_OUT = -104 + const val UNKNOWN_HOST = -105 + const val HTTP_NOT_FOUND = -106 + const val WRITE_PERMISSION_DENIED = -107 + const val N0_STORAGE_SPACE = -108 + const val SERVER_ERROR = -110 + const val FILE_NOT_FOUND = -111 + const val REQUEST_ALREADY_EXIST = -113 + const val ENQUEUE_ERROR = -117 } \ No newline at end of file diff --git a/fetchmigrator/src/main/java/com/tonyodev/fetchmigrator/fetch1/FetchConst.kt b/fetchmigrator/src/main/java/com/tonyodev/fetchmigrator/fetch1/FetchConst.kt index 5eed6ae6..431a99dc 100644 --- a/fetchmigrator/src/main/java/com/tonyodev/fetchmigrator/fetch1/FetchConst.kt +++ b/fetchmigrator/src/main/java/com/tonyodev/fetchmigrator/fetch1/FetchConst.kt @@ -55,58 +55,58 @@ internal interface FetchConst { * Error ID used when a download request fails because the local file could not be created * on the device or SD Card. */ - val ERROR_FILE_NOT_CREATED = ErrorUtils.FILE_NOT_CREATED + const val ERROR_FILE_NOT_CREATED = ErrorUtils.FILE_NOT_CREATED /** * Error ID used when a download request fails because the application does not have * permission to write to the file path on the device or SD Card. */ - val ERROR_WRITE_PERMISSION_DENIED = ErrorUtils.WRITE_PERMISSION_DENIED + const val ERROR_WRITE_PERMISSION_DENIED = ErrorUtils.WRITE_PERMISSION_DENIED /** * Error ID used when a download request fails because there is no storage space left of the * device or SD Card. */ - val ERROR_NO_STORAGE_SPACE = ErrorUtils.N0_STORAGE_SPACE + const val ERROR_NO_STORAGE_SPACE = ErrorUtils.N0_STORAGE_SPACE /** * Error ID used when a download request fails because the requested download url could * not be found. */ - val ERROR_HTTP_NOT_FOUND = ErrorUtils.HTTP_NOT_FOUND + const val ERROR_HTTP_NOT_FOUND = ErrorUtils.HTTP_NOT_FOUND /** * Error ID used when a download request fails because a successfully connection * could not be made with the server. */ - val ERROR_UNKNOWN_HOST = ErrorUtils.UNKNOWN_HOST + const val ERROR_UNKNOWN_HOST = ErrorUtils.UNKNOWN_HOST /** * Error ID used when a download request fails because the connection timed out. */ - val ERROR_CONNECTION_TIMEOUT = ErrorUtils.CONNECTION_TIMED_OUT + const val ERROR_CONNECTION_TIMEOUT = ErrorUtils.CONNECTION_TIMED_OUT /** * Error ID used when a download request fails because of an unknown server error. */ - val ERROR_SERVER_ERROR = ErrorUtils.SERVER_ERROR + const val ERROR_SERVER_ERROR = ErrorUtils.SERVER_ERROR /** * Error ID used when a download request fails because the local file is not found after a * download begins at the requested file path. */ - val ERROR_FILE_NOT_FOUND = ErrorUtils.FILE_NOT_FOUND + const val ERROR_FILE_NOT_FOUND = ErrorUtils.FILE_NOT_FOUND /** * Error ID used when a download request is not queued because a request with the * local file path already exists in the FetchService database and is active. */ - val ERROR_REQUEST_ALREADY_EXIST = ErrorUtils.REQUEST_ALREADY_EXIST + const val ERROR_REQUEST_ALREADY_EXIST = ErrorUtils.REQUEST_ALREADY_EXIST /** * Error ID used when a request could not be enqueued. */ - val ERROR_ENQUEUE_ERROR = ErrorUtils.ENQUEUE_ERROR + const val ERROR_ENQUEUE_ERROR = ErrorUtils.ENQUEUE_ERROR } diff --git a/fetchmigrator/src/main/java/com/tonyodev/fetchmigrator/helpers/TypeConverters.kt b/fetchmigrator/src/main/java/com/tonyodev/fetchmigrator/helpers/TypeConverters.kt index b8281cce..5a96a482 100644 --- a/fetchmigrator/src/main/java/com/tonyodev/fetchmigrator/helpers/TypeConverters.kt +++ b/fetchmigrator/src/main/java/com/tonyodev/fetchmigrator/helpers/TypeConverters.kt @@ -6,10 +6,12 @@ import com.tonyodev.fetch2.Priority import com.tonyodev.fetch2.Status import com.tonyodev.fetch2.database.DownloadInfo import com.tonyodev.fetchmigrator.fetch1.DatabaseHelper +import com.tonyodev.fetchmigrator.fetch1.DownloadTransferPair import com.tonyodev.fetchmigrator.fetch1.FetchConst import org.json.JSONObject -fun v1CursorToV2DownloadInfo(cursor: Cursor): DownloadInfo { +fun v1CursorToV2DownloadInfo(cursor: Cursor): DownloadTransferPair { + val id = cursor.getLong(DatabaseHelper.INDEX_ID) val status = cursor.getInt(DatabaseHelper.INDEX_COLUMN_STATUS) val url = cursor.getString(DatabaseHelper.INDEX_COLUMN_URL) val file = cursor.getString(DatabaseHelper.INDEX_COLUMN_FILEPATH) @@ -20,6 +22,7 @@ fun v1CursorToV2DownloadInfo(cursor: Cursor): DownloadInfo { val headers = cursor.getString(DatabaseHelper.INDEX_COLUMN_HEADERS) val downloadInfo = DownloadInfo() + downloadInfo.id = (url.hashCode() * 31) + file.hashCode() downloadInfo.url = url downloadInfo.file = file downloadInfo.status = getStatusFromV1ForV2(status) @@ -28,8 +31,7 @@ fun v1CursorToV2DownloadInfo(cursor: Cursor): DownloadInfo { downloadInfo.headers = fromHeaderStringToMap(headers) downloadInfo.priority = getPriorityFromV1ForV2(priority) downloadInfo.error = getErrorFromV1ForV2(error) - downloadInfo.id = downloadInfo.request.id - return downloadInfo + return DownloadTransferPair(downloadInfo, id) } fun getStatusFromV1ForV2(v1StatusCode: Int): Status { @@ -55,6 +57,7 @@ fun getPriorityFromV1ForV2(v1PriorityCode: Int): Priority { fun getErrorFromV1ForV2(v1ErrorCode: Int): Error { return when (v1ErrorCode) { + -1 -> Error.NONE FetchConst.ERROR_FILE_NOT_CREATED -> Error.FILE_NOT_CREATED FetchConst.ERROR_CONNECTION_TIMEOUT -> Error.CONNECTION_TIMED_OUT FetchConst.ERROR_UNKNOWN_HOST -> Error.UNKNOWN_HOST diff --git a/versions.gradle b/versions.gradle index cf4788d7..985a84b9 100644 --- a/versions.gradle +++ b/versions.gradle @@ -16,6 +16,6 @@ ext { rxAndroid2_version = "2.0.2" timber_version = "4.7.0" novoda_bintray_version = "0.8.0" - library_version = "2.0.0-RC14" - library_version_code = 15 + library_version = "2.0.0-RC15" + library_version_code = 16 } \ No newline at end of file