diff --git a/Aria/src/main/java/com/arialyy/aria/core/AriaManager.java b/Aria/src/main/java/com/arialyy/aria/core/AriaManager.java index 9d26dd06..f920f836 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/AriaManager.java +++ b/Aria/src/main/java/com/arialyy/aria/core/AriaManager.java @@ -80,6 +80,7 @@ import org.xml.sax.SAXException; private UploadConfig mUConfig; private AppConfig mAConfig; private DGroupConfig mDGConfig; + private File[] files; private AriaManager(Context context) { APP = context.getApplicationContext(); @@ -104,11 +105,13 @@ import org.xml.sax.SAXException; } private void initDb(Context context) { - String dbBase = context.getFilesDir().getPath() + context.getPackageName() + "/databases/"; - File db = new File(dbBase + "AriaLyyDb"); - File dbConfig = new File(dbBase + "AriaLyyDb-journal"); + // 这个地方错误了,获取数据库路径见:https://www.jianshu.com/p/815c9efc5449 + String oldDbName = "AriaLyyDb"; + String oldDbPath = context.getDatabasePath(oldDbName).getPath(); + File db = new File(oldDbPath); + File dbConfig = new File(String.format("%s/%s", db.getParent(), "AriaLyyDb-journal")); if (db.exists()) { - db.renameTo(new File(dbBase + "AndroidAria.db")); + db.renameTo(new File(String.format("%s/%s", db.getParent(), "AndroidAria.db"))); // 如果数据库是在/data/data/{packagename}/databases/下面,journal文件因权限问题将无法删除和重命名 if (dbConfig.exists()) { dbConfig.delete(); diff --git a/Aria/src/main/java/com/arialyy/aria/core/common/ftp/FTPSConfig.java b/Aria/src/main/java/com/arialyy/aria/core/common/ftp/FTPSDelegate.java similarity index 76% rename from Aria/src/main/java/com/arialyy/aria/core/common/ftp/FTPSConfig.java rename to Aria/src/main/java/com/arialyy/aria/core/common/ftp/FTPSDelegate.java index 56dab9c7..5188d59d 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/common/ftp/FTPSConfig.java +++ b/Aria/src/main/java/com/arialyy/aria/core/common/ftp/FTPSDelegate.java @@ -22,14 +22,14 @@ import com.arialyy.aria.core.inf.AbsTarget; import com.arialyy.aria.core.inf.ITarget; /** - * FTP SSL/TSL配置 + * FTP SSL/TSL 参数委托 */ -public class FTPSConfig implements ITarget { - private final String TAG = "FTPSConfig"; +public class FTPSDelegate implements ITarget { + private final String TAG = "FTPSDelegate"; private TARGET mTarget; private FtpUrlEntity mUrlEntity; - public FTPSConfig(TARGET target) { + public FTPSDelegate(TARGET target) { mTarget = target; mUrlEntity = mTarget.getTaskWrapper().asFtp().getUrlEntity(); } @@ -39,7 +39,7 @@ public class FTPSConfig implements ITarget { * * @param protocol {@link ProtocolType} */ - public FTPSConfig setProtocol(@ProtocolType String protocol) { + public FTPSDelegate setProtocol(@ProtocolType String protocol) { if (TextUtils.isEmpty(protocol)) { throw new NullPointerException("协议为空"); } @@ -52,7 +52,7 @@ public class FTPSConfig implements ITarget { * * @param keyAlias 别名 */ - public FTPSConfig setAlias(String keyAlias) { + public FTPSDelegate setAlias(String keyAlias) { if (TextUtils.isEmpty(keyAlias)) { throw new NullPointerException("别名为空"); } @@ -65,7 +65,7 @@ public class FTPSConfig implements ITarget { * * @param storePass 私钥密码 */ - public FTPSConfig setStorePass(String storePass) { + public FTPSDelegate setStorePass(String storePass) { if (TextUtils.isEmpty(storePass)) { throw new NullPointerException("证书密码为空"); } @@ -78,7 +78,7 @@ public class FTPSConfig implements ITarget { * * @param storePath 证书路径 */ - public FTPSConfig setStorePath(String storePath) { + public FTPSDelegate setStorePath(String storePath) { if (TextUtils.isEmpty(storePath)) { throw new NullPointerException("证书路径为空"); } @@ -101,4 +101,20 @@ public class FTPSConfig implements ITarget { @Override public void cancel() { mTarget.cancel(); } + + @Override public void save() { + mTarget.save(); + } + + @Override public void cancel(boolean removeFile) { + mTarget.cancel(removeFile); + } + + @Override public void reTry() { + mTarget.reTry(); + } + + @Override public void reStart() { + mTarget.reStart(); + } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/common/http/GetDelegate.java b/Aria/src/main/java/com/arialyy/aria/core/common/http/GetDelegate.java index e1ed87e4..4fcccbff 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/common/http/GetDelegate.java +++ b/Aria/src/main/java/com/arialyy/aria/core/common/http/GetDelegate.java @@ -21,7 +21,7 @@ import com.arialyy.aria.core.inf.AbsTarget; /** * get处理委托类 */ -public class GetDelegate extends BaseTarget { +public class GetDelegate extends HttpDelegate { public GetDelegate(TARGET target) { super(target); diff --git a/Aria/src/main/java/com/arialyy/aria/core/common/http/BaseTarget.java b/Aria/src/main/java/com/arialyy/aria/core/common/http/HttpDelegate.java similarity index 82% rename from Aria/src/main/java/com/arialyy/aria/core/common/http/BaseTarget.java rename to Aria/src/main/java/com/arialyy/aria/core/common/http/HttpDelegate.java index 422e7f4d..3caf18a9 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/common/http/BaseTarget.java +++ b/Aria/src/main/java/com/arialyy/aria/core/common/http/HttpDelegate.java @@ -25,11 +25,15 @@ import com.arialyy.aria.util.ALog; import java.util.HashMap; import java.util.Map; -class BaseTarget implements ITarget { +/** + * HTTP参数委托 + * @param + */ +class HttpDelegate implements ITarget { private static final String TAG = "PostDelegate"; TARGET mTarget; - public BaseTarget(TARGET target){ + HttpDelegate(TARGET target) { mTarget = target; } @@ -63,18 +67,34 @@ class BaseTarget implements ITarget { } @Override public void start() { - + mTarget.start(); } @Override public void stop() { - + mTarget.stop(); } @Override public void resume() { - + mTarget.resume(); } @Override public void cancel() { + mTarget.cancel(); + } + + @Override public void save() { + mTarget.save(); + } + + @Override public void cancel(boolean removeFile) { + mTarget.cancel(removeFile); + } + + @Override public void reTry() { + mTarget.reTry(); + } + @Override public void reStart() { + mTarget.reStart(); } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/common/http/PostDelegate.java b/Aria/src/main/java/com/arialyy/aria/core/common/http/PostDelegate.java index 97f1e63f..d01b8cb9 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/common/http/PostDelegate.java +++ b/Aria/src/main/java/com/arialyy/aria/core/common/http/PostDelegate.java @@ -21,7 +21,7 @@ import com.arialyy.aria.core.inf.AbsTarget; /** * post处理委托类 */ -public class PostDelegate extends BaseTarget { +public class PostDelegate extends HttpDelegate { public PostDelegate(TARGET target) { super(target); diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadReceiver.java b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadReceiver.java index 71a43a48..d5814539 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadReceiver.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadReceiver.java @@ -322,12 +322,13 @@ public class DownloadReceiver extends AbsReceiver { } /** - * 分页获取所有普通下载任务,如果页数大于总页数,返回null + * 分页获取所有普通下载任务 * 获取未完成的普通任务列表{@link #getAllNotCompleteTask()} * 获取已经完成的普通任务列表{@link #getAllCompleteTask()} * * @param page 当前页,不能小于1 * @param num 每页数量,不能小于1 + * @return 如果页数大于总页数,返回null */ public List getTaskList(int page, int num) { CheckUtil.checkPageParams(page, num); @@ -344,10 +345,11 @@ public class DownloadReceiver extends AbsReceiver { } /** - * 分页获取所有未完成的普通下载任务,如果页数大于总页数,返回null + * 分页获取所有未完成的普通下载任务 * * @param page 当前页,不能小于1 * @param num 每页数量,不能小于1 + * @return 如果页数大于总页数,返回null */ public List getAllNotCompleteTask(int page, int num) { CheckUtil.checkPageParams(page, num); @@ -364,7 +366,11 @@ public class DownloadReceiver extends AbsReceiver { } /** - * 分页获取所有已经完成的普通任务,如果页数大于总页数,返回null + * 分页获取所有已经完成的普通任务 + * + * @param page 当前页,不能小于1 + * @param num 每页数量,不能小于1 + * @return 如果页数大于总页数,返回null */ public List getAllCompleteTask(int page, int num) { CheckUtil.checkPageParams(page, num); @@ -389,6 +395,25 @@ public class DownloadReceiver extends AbsReceiver { return entities; } + /** + * 分页获取祝贺任务列表 + * + * @param page 当前页,不能小于1 + * @param num 每页数量,不能小于1 + * @return 如果没有任务组列表,则返回null + */ + public List getGroupTaskList(int page, int num) { + List wrappers = DbEntity.findRelationData(DGEntityWrapper.class, page, num); + if (wrappers == null || wrappers.isEmpty()) { + return null; + } + List entities = new ArrayList<>(); + for (DGEntityWrapper wrapper : wrappers) { + entities.add(wrapper.groupEntity); + } + return entities; + } + /** * 获取普通任务和任务组的任务列表 */ diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTarget.java b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTarget.java index 0e6b8c7d..386f7f63 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTarget.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTarget.java @@ -44,6 +44,7 @@ public class DownloadTarget extends BaseNormalTarget /** * Post处理 */ + @CheckResult public PostDelegate asPost() { return new PostDelegate<>(this); } @@ -51,6 +52,7 @@ public class DownloadTarget extends BaseNormalTarget /** * get参数传递 */ + @CheckResult public GetDelegate asGet(){ return new GetDelegate<>(this); } diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/FtpDirDownloadTarget.java b/Aria/src/main/java/com/arialyy/aria/core/download/FtpDirDownloadTarget.java index c28393ae..e44d3a2b 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/FtpDirDownloadTarget.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/FtpDirDownloadTarget.java @@ -18,7 +18,7 @@ package com.arialyy.aria.core.download; import android.support.annotation.CheckResult; import android.text.TextUtils; import com.arialyy.aria.core.FtpUrlEntity; -import com.arialyy.aria.core.common.ftp.FTPSConfig; +import com.arialyy.aria.core.common.ftp.FTPSDelegate; import com.arialyy.aria.core.common.ftp.FtpDelegate; import com.arialyy.aria.core.inf.AbsTaskWrapper; import com.arialyy.aria.core.inf.IFtpTarget; @@ -115,13 +115,13 @@ public class FtpDirDownloadTarget extends BaseGroupTarget /** * 是否是FTPS协议 - * 如果是FTPS协议,需要使用{@link FTPSConfig#setStorePath(String)} 、{@link FTPSConfig#setAlias(String)} + * 如果是FTPS协议,需要使用{@link FTPSDelegate#setStorePath(String)} 、{@link FTPSDelegate#setAlias(String)} * 设置证书信息 */ @CheckResult - public FTPSConfig asFtps() { + public FTPSDelegate asFtps() { mTaskWrapper.asFtp().getUrlEntity().isFtps = true; - return new FTPSConfig<>(this); + return new FTPSDelegate<>(this); } @CheckResult diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/FtpDownloadTarget.java b/Aria/src/main/java/com/arialyy/aria/core/download/FtpDownloadTarget.java index b7d339b0..14b3e4d6 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/FtpDownloadTarget.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/FtpDownloadTarget.java @@ -18,9 +18,8 @@ package com.arialyy.aria.core.download; import android.support.annotation.CheckResult; import android.support.annotation.NonNull; import android.text.TextUtils; -import com.arialyy.aria.core.common.ftp.FTPSConfig; +import com.arialyy.aria.core.common.ftp.FTPSDelegate; import com.arialyy.aria.core.common.ftp.FtpDelegate; -import com.arialyy.aria.core.common.ftp.FtpTaskDelegate; import com.arialyy.aria.core.inf.AbsTaskWrapper; import com.arialyy.aria.core.inf.IFtpTarget; import com.arialyy.aria.util.ALog; @@ -55,13 +54,13 @@ public class FtpDownloadTarget extends BaseNormalTarget /** * 是否是FTPS协议 - * 如果是FTPS协议,需要使用{@link FTPSConfig#setStorePath(String)} 、{@link FTPSConfig#setAlias(String)} + * 如果是FTPS协议,需要使用{@link FTPSDelegate#setStorePath(String)} 、{@link FTPSDelegate#setAlias(String)} * 设置证书信息 */ @CheckResult - public FTPSConfig asFtps() { + public FTPSDelegate asFtps() { mTaskWrapper.asFtp().getUrlEntity().isFtps = true; - return new FTPSConfig<>(this); + return new FTPSDelegate<>(this); } @Override protected boolean checkEntity() { diff --git a/Aria/src/main/java/com/arialyy/aria/core/inf/AbsTarget.java b/Aria/src/main/java/com/arialyy/aria/core/inf/AbsTarget.java index f43046ab..44ad1b90 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/inf/AbsTarget.java +++ b/Aria/src/main/java/com/arialyy/aria/core/inf/AbsTarget.java @@ -190,13 +190,12 @@ public abstract class AbsTarget cmds = new ArrayList<>(); int taskType = checkTaskType(); @@ -289,7 +290,7 @@ public abstract class AbsTarget /** * 是否是FTPS协议 - * 如果是FTPS协议,需要使用{@link FTPSConfig#setStorePath(String)} 、{@link FTPSConfig#setAlias(String)} + * 如果是FTPS协议,需要使用{@link FTPSDelegate#setStorePath(String)} 、{@link FTPSDelegate#setAlias(String)} * 设置证书信息 */ @CheckResult - public FTPSConfig asFtps() { + public FTPSDelegate asFtps() { if (mTaskWrapper.asFtp().getUrlEntity() == null) { FtpUrlEntity urlEntity = new FtpUrlEntity(); urlEntity.isFtps = true; mTaskWrapper.asFtp().setUrlEntity(urlEntity); } - return new FTPSConfig<>(this); + return new FTPSDelegate<>(this); } @CheckResult diff --git a/Aria/src/main/java/com/arialyy/aria/core/upload/UploadReceiver.java b/Aria/src/main/java/com/arialyy/aria/core/upload/UploadReceiver.java index 516404f8..fa0b7670 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/upload/UploadReceiver.java +++ b/Aria/src/main/java/com/arialyy/aria/core/upload/UploadReceiver.java @@ -106,12 +106,13 @@ public class UploadReceiver extends AbsReceiver { } /** - * 分页获取所有普通上传任务,如果页数大于总页数,返回null + * 分页获取所有普通上传任务 * 获取未完成的普通任务列表{@link #getAllNotCompleteTask()} * 获取已经完成的普通任务列表{@link #getAllCompleteTask()} * * @param page 当前页,不能小于1 * @param num 每页数量,不能小于1 + * @return 如果页数大于总页数,返回null */ public List getTaskList(int page, int num) { CheckUtil.checkPageParams(page, num); @@ -128,10 +129,11 @@ public class UploadReceiver extends AbsReceiver { } /** - * 分页获取所有未完成的普通上传任务,如果页数大于总页数,返回null + * 分页获取所有未完成的普通上传任务 * * @param page 当前页,不能小于1 * @param num 每页数量,不能小于1 + * @return 如果页数大于总页数,返回null */ public List getAllNotCompleteTask(int page, int num) { CheckUtil.checkPageParams(page, num); @@ -140,7 +142,7 @@ public class UploadReceiver extends AbsReceiver { } /** - * 获取所有已经完成的普通任务,如果页数大于总页数,返回null + * 获取所有已经完成的普通任务 */ public List getAllCompleteTask() { return DbEntity.findDatas(UploadEntity.class, "isGroupChild=? and isComplete=?", "false", @@ -148,7 +150,11 @@ public class UploadReceiver extends AbsReceiver { } /** - * 分页获取所有已经完成的普通任务,如果页数大于总页数,返回null + * 分页获取所有已经完成的普通任务 + * + * @param page 当前页,不能小于1 + * @param num 每页数量,不能小于1 + * @return 如果页数大于总页数,返回null */ public List getAllCompleteTask(int page, int num) { CheckUtil.checkPageParams(page, num); diff --git a/Aria/src/main/java/com/arialyy/aria/orm/AbsDelegate.java b/Aria/src/main/java/com/arialyy/aria/orm/AbsDelegate.java index eafac17d..5fffaccd 100644 --- a/Aria/src/main/java/com/arialyy/aria/orm/AbsDelegate.java +++ b/Aria/src/main/java/com/arialyy/aria/orm/AbsDelegate.java @@ -33,7 +33,6 @@ abstract class AbsDelegate { static final int INSERT_DATA = 2; static final int MODIFY_DATA = 3; static final int FIND_DATA = 4; - static final int FIND_ALL_DATA = 5; static final int DEL_DATA = 6; static final int ROW_ID = 7; static final int RELATION = 8; @@ -65,10 +64,7 @@ abstract class AbsDelegate { str = "修改数据 >>>> "; break; case FIND_DATA: - str = "查询一行数据 >>>> "; - break; - case FIND_ALL_DATA: - str = "遍历整个数据库 >>>> "; + str = "查询数据 >>>> "; break; case ROW_ID: str = "查询RowId >>> "; diff --git a/Aria/src/main/java/com/arialyy/aria/orm/DBConfig.java b/Aria/src/main/java/com/arialyy/aria/orm/DBConfig.java index 0c8e6baf..59e3394a 100644 --- a/Aria/src/main/java/com/arialyy/aria/orm/DBConfig.java +++ b/Aria/src/main/java/com/arialyy/aria/orm/DBConfig.java @@ -35,7 +35,7 @@ class DBConfig { /*adb pull /mnt/sdcard/Android/data/com.arialyy.simple/files/DB/AriaLyyDb d:/db*/ static Map mapping = new HashMap<>(); static String DB_NAME; - static int VERSION = 44; + static int VERSION = 45; /** * 是否将数据库保存在Sd卡,{@code true} 是 diff --git a/Aria/src/main/java/com/arialyy/aria/orm/DbEntity.java b/Aria/src/main/java/com/arialyy/aria/orm/DbEntity.java index 07897a6d..1e227f5a 100644 --- a/Aria/src/main/java/com/arialyy/aria/orm/DbEntity.java +++ b/Aria/src/main/java/com/arialyy/aria/orm/DbEntity.java @@ -30,15 +30,11 @@ public abstract class DbEntity { } - ///** - // * 保存关联数据 - // */ - //public static void saveRelationData(AbsDbWrapper wrapper) { - // DelegateWrapper.getInstance().saveRelationData(wrapper); - //} - /** * 查询关联数据 + * + * DbEntity.findRelationData(DGEntityWrapper.class, "downloadUrl=?", downloadUrl); + * * * @param expression 查询条件 */ @@ -47,6 +43,26 @@ public abstract class DbEntity { return DelegateWrapper.getInstance().findRelationData(clazz, expression); } + /** + * 分页查询关联数据 + * + * + * DbEntity.findRelationData(DGEntityWrapper.class, 0, 10, "downloadUrl=?", downloadUrl); + * + * + * @param expression 查询条件 + * @param page 需要查询的页数,从1开始,如果page小于1 或 num 小于1,返回null + * @param num 每页返回的数量 + * @return 没有数据返回null,如果页数大于总页数,返回null + */ + public static List findRelationData(Class clazz, int page, int num, + String... expression) { + if (page < 1 || num < 1) { + return null; + } + return DelegateWrapper.getInstance().findRelationData(clazz, page, num, expression); + } + /** * 检查某个字段的值是否存在 * @@ -91,7 +107,7 @@ public abstract class DbEntity { /** * 查询一组数据 * - * DownloadEntity.findFirst(DownloadEntity.class, "downloadUrl=?", downloadUrl); + * DbEntity.findFirst(DownloadEntity.class, "downloadUrl=?", downloadUrl); * * * @return 没有数据返回null @@ -103,7 +119,7 @@ public abstract class DbEntity { /** * 分页查询数据 * - * DownloadEntity.findFirst(DownloadEntity.class, 0, 10, "downloadUrl=?", downloadUrl); + * DbEntity.findFirst(DownloadEntity.class, 0, 10, "downloadUrl=?", downloadUrl); * * * @param page 需要查询的页数,从1开始,如果page小于1 或 num 小于1,返回null @@ -121,7 +137,7 @@ public abstract class DbEntity { /** * 模糊查询一组数据 * - * DownloadEntity.findDatas(DownloadEntity.class, "downloadUrl like http://"); + * DbEntity.findDataByFuzzy(DownloadEntity.class, "downloadUrl like http://"); * * * @return 没有数据返回null @@ -133,7 +149,7 @@ public abstract class DbEntity { /** * 模糊查询一组数据 * - * DownloadEntity.findDatas(DownloadEntity.class, "downloadUrl like http://"); + * DbEntity.findDataByFuzzy(DownloadEntity.class, 0, 10, "downloadUrl like http://"); * * * @param page 需要查询的页数,从1开始,如果page小于1 或 num 小于1,返回null @@ -148,7 +164,7 @@ public abstract class DbEntity { /** * 查询一行数据 * - * DownloadEntity.findFirst(DownloadEntity.class, "downloadUrl=?", downloadUrl); + * DbEntity.findFirst(DownloadEntity.class, "downloadUrl=?", downloadUrl); * * * @return 没有数据返回null @@ -220,7 +236,7 @@ public abstract class DbEntity { /** * 根据条件删除数据 * - * DownloadEntity.deleteData(DownloadEntity.class, "downloadUrl=?", downloadUrl); + * DbEntity.deleteData(DownloadEntity.class, "downloadUrl=?", downloadUrl); * */ public static void deleteData(Class clazz, String... expression) { diff --git a/Aria/src/main/java/com/arialyy/aria/orm/DelegateCommon.java b/Aria/src/main/java/com/arialyy/aria/orm/DelegateCommon.java index f75695aa..adea7c9b 100644 --- a/Aria/src/main/java/com/arialyy/aria/orm/DelegateCommon.java +++ b/Aria/src/main/java/com/arialyy/aria/orm/DelegateCommon.java @@ -71,7 +71,14 @@ class DelegateCommon extends AbsDelegate { return tableExists(db, CommonUtil.getClassName(clazz)); } - private boolean tableExists(SQLiteDatabase db, String tableName) { + + /** + * 查找表是否存在 + * + * @param tableName 表名 + * @return true,该数据库实体对应的表存在;false,不存在 + */ + boolean tableExists(SQLiteDatabase db, String tableName) { db = checkDb(db); Cursor cursor = null; try { @@ -104,8 +111,8 @@ class DelegateCommon extends AbsDelegate { boolean checkDataExist(SQLiteDatabase db, Class clazz, String... expression) { db = checkDb(db); CheckUtil.checkSqlExpression(expression); - String sql = - "SELECT rowid, * FROM " + CommonUtil.getClassName(clazz) + " WHERE " + expression[0] + " "; + String sql = String.format("SELECT rowid, * FROM %s WHERE %s ", CommonUtil.getClassName(clazz), + expression[0]); sql = sql.replace("?", "%s"); Object[] params = new String[expression.length - 1]; for (int i = 0, len = params.length; i < len; i++) { diff --git a/Aria/src/main/java/com/arialyy/aria/orm/DelegateFind.java b/Aria/src/main/java/com/arialyy/aria/orm/DelegateFind.java index 383da34a..0ebd9534 100644 --- a/Aria/src/main/java/com/arialyy/aria/orm/DelegateFind.java +++ b/Aria/src/main/java/com/arialyy/aria/orm/DelegateFind.java @@ -47,6 +47,53 @@ class DelegateFind extends AbsDelegate { private DelegateFind() { } + /** + * 获取{@link One}和{@link Many}注解的字段 + * + * @return 返回[OneField, ManyField] ,如果注解依赖错误返回null + */ + private Field[] getOneAndManyField(Class clazz) { + Field[] om = new Field[2]; + Field[] fields = clazz.getDeclaredFields(); + Field one = null, many = null; + boolean hasOne = false, hasMany = false; + for (Field field : fields) { + if (SqlUtil.isOne(field)) { + if (hasOne) { + ALog.w(TAG, "查询数据失败,实体中有多个@One 注解"); + return null; + } + hasOne = true; + one = field; + } + if (SqlUtil.isMany(field)) { + if (hasMany) { + ALog.w(TAG, "查询数据失败,实体中有多个@Many 注解"); + return null; + } + if (!field.getType().isAssignableFrom(List.class)) { + ALog.w(TAG, "查询数据失败,@Many 注解的类型不是List"); + return null; + } + hasMany = true; + many = field; + } + } + + if (one == null || many == null) { + ALog.w(TAG, "查询数据失败,实体中没有@One或@Many注解"); + return null; + } + + if (many.getType() != List.class) { + ALog.w(TAG, "查询数据失败,@Many注解的字段必须是List"); + return null; + } + om[0] = one; + om[1] = many; + return om; + } + /** * 查找一对多的关联数据 * 如果查找不到数据或实体没有被{@link Wrapper}注解,将返回null @@ -56,45 +103,40 @@ class DelegateFind extends AbsDelegate { */ List findRelationData(SQLiteDatabase db, Class clazz, String... expression) { - db = checkDb(db); - - if (SqlUtil.isWrapper(clazz)) { - StringBuilder sb = new StringBuilder(); - Field[] fields = clazz.getDeclaredFields(); - Field one = null, many = null; - boolean hasOne = false, hasMany = false; - for (Field field : fields) { - if (SqlUtil.isOne(field)) { - if (hasOne) { - ALog.w(TAG, "查询数据失败,实体中有多个@One 注解"); - return null; - } - hasOne = true; - one = field; - } - if (SqlUtil.isMany(field)) { - if (hasMany) { - ALog.w(TAG, "查询数据失败,实体中有多个@Many 注解"); - return null; - } - if (!field.getType().isAssignableFrom(List.class)) { - ALog.w(TAG, "查询数据失败,@Many 注解的类型不是List"); - return null; - } - hasMany = true; - many = field; - } - } + return exeRelationSql(db, clazz, -1, -1, expression); + } - if (one == null || many == null) { - ALog.w(TAG, "查询数据失败,实体中没有@One或@Many注解"); - return null; - } + /** + * 查找一对多的关联数据 + * 如果查找不到数据或实体没有被{@link Wrapper}注解,将返回null + * 如果实体中没有{@link One}或{@link Many}注解,将返回null + * 如果实体中有多个{@link One}或{@link Many}注解,将返回nul + * {@link One} 的注解对象必须是{@link DbEntity},{@link Many}的注解对象必须是List,并且List中的类型必须是{@link DbEntity} + */ + List findRelationData(SQLiteDatabase db, Class clazz, + int page, int num, String... expression) { + if (page < 1 || num < 1) { + return null; + } + return exeRelationSql(db, clazz, page, num, expression); + } - if (many.getType() != List.class) { - ALog.w(TAG, "查询数据失败,@Many注解的字段必须是List"); + /** + * 执行关联查询,如果不需要分页,page和num传-1 + * + * @param page 当前页 + * @param num 一页的数量 + */ + private List exeRelationSql(SQLiteDatabase db, Class clazz, + int page, int num, String... expression) { + db = checkDb(db); + if (SqlUtil.isWrapper(clazz)) { + Field[] om = getOneAndManyField(clazz); + if (om == null) { return null; } + StringBuilder sb = new StringBuilder(); + Field one = om[0], many = om[1]; try { Many m = many.getAnnotation(Many.class); Class parentClazz = Class.forName(one.getType().getName()); @@ -176,7 +218,10 @@ class DelegateFind extends AbsDelegate { } else { sql = sb.toString(); } - //ALog.d(TAG, sql); + if (page != -1 && num != -1) { + sql = sql.concat(String.format(" LIMIT %s,%s", (page - 1) * num, num)); + } + print(RELATION, sql); Cursor cursor = db.rawQuery(sql, null); List data = @@ -189,7 +234,7 @@ class DelegateFind extends AbsDelegate { e.printStackTrace(); } } else { - ALog.w(TAG, "查询数据失败,实体类没有使用@Wrapper 注解"); + ALog.e(TAG, "查询数据失败,实体类没有使用@Wrapper 注解"); return null; } return null; @@ -346,12 +391,7 @@ class DelegateFind extends AbsDelegate { String[] params = new String[expression.length - 1]; System.arraycopy(expression, 1, params, 0, params.length); - print(FIND_DATA, sql); - Cursor cursor = db.rawQuery(sql, params); - List data = cursor.getCount() > 0 ? newInstanceEntity(clazz, cursor) : null; - closeCursor(cursor); - close(db); - return data; + return exeNormalDataSql(db, clazz, sql, params); } /** @@ -371,12 +411,7 @@ class DelegateFind extends AbsDelegate { String[] params = new String[expression.length - 1]; System.arraycopy(expression, 1, params, 0, params.length); - print(FIND_DATA, sql); - Cursor cursor = db.rawQuery(sql, params); - List data = cursor.getCount() > 0 ? newInstanceEntity(clazz, cursor) : null; - closeCursor(cursor); - close(db); - return data; + return exeNormalDataSql(db, clazz, sql, params); } /** @@ -393,12 +428,7 @@ class DelegateFind extends AbsDelegate { } String sql = String.format("SELECT rowid, * FROM %s, WHERE %s", CommonUtil.getClassName(clazz), conditions); - print(FIND_DATA, sql); - Cursor cursor = db.rawQuery(sql, null); - List data = cursor.getCount() > 0 ? newInstanceEntity(clazz, cursor) : null; - closeCursor(cursor); - close(db); - return data; + return exeNormalDataSql(db, clazz, sql, null); } /** @@ -418,12 +448,7 @@ class DelegateFind extends AbsDelegate { } String sql = String.format("SELECT rowid, * FROM %s WHERE %s LIMIT %s,%s", CommonUtil.getClassName(clazz), conditions, (page - 1) * num, num); - print(FIND_DATA, sql); - Cursor cursor = db.rawQuery(sql, null); - List data = cursor.getCount() > 0 ? newInstanceEntity(clazz, cursor) : null; - closeCursor(cursor); - close(db); - return data; + return exeNormalDataSql(db, clazz, sql, null); } /** @@ -431,10 +456,20 @@ class DelegateFind extends AbsDelegate { */ List findAllData(SQLiteDatabase db, Class clazz) { db = checkDb(db); - StringBuilder sb = new StringBuilder(); - sb.append("SELECT rowid, * FROM ").append(CommonUtil.getClassName(clazz)); - print(FIND_ALL_DATA, sb.toString()); - Cursor cursor = db.rawQuery(sb.toString(), null); + String sql = String.format("SELECT rowid, * FROM %s", CommonUtil.getClassName(clazz)); + return exeNormalDataSql(db, clazz, sql, null); + } + + /** + * 执行查询普通数据的sql语句,并创建对象 + * + * @param sql sql 查询语句 + * @param selectionArgs 查询参数,如何sql语句中查询条件含有'?'则该参数不能为空 + */ + private List exeNormalDataSql(SQLiteDatabase db, Class clazz, + String sql, String[] selectionArgs) { + print(FIND_DATA, sql); + Cursor cursor = db.rawQuery(sql, selectionArgs); List data = cursor.getCount() > 0 ? newInstanceEntity(clazz, cursor) : null; closeCursor(cursor); close(db); diff --git a/Aria/src/main/java/com/arialyy/aria/orm/DelegateUpdate.java b/Aria/src/main/java/com/arialyy/aria/orm/DelegateUpdate.java index 49c80d2d..b2d05d97 100644 --- a/Aria/src/main/java/com/arialyy/aria/orm/DelegateUpdate.java +++ b/Aria/src/main/java/com/arialyy/aria/orm/DelegateUpdate.java @@ -34,51 +34,7 @@ class DelegateUpdate extends AbsDelegate { private DelegateUpdate() { } - ///** - // * 添加或更新关联数据 - // */ - //void saveRelationData(SQLiteDatabase db, AbsDbWrapper wrapper) { - // Class clazz = wrapper.getClass(); - // List fields = CommonUtil.getAllFields(clazz); - // DbEntity one = null; - // Object many = null; - // try { - // for (Field field : fields) { - // if (SqlUtil.isOne(field)) { - // one = (DbEntity) field.get(wrapper); - // } else if (SqlUtil.isMany(field)) { - // many = field.get(wrapper); - // } - // } - // if (one == null) { - // ALog.w(TAG, "保存关联数据失败,@One注解的字段为null"); - // return; - // } - // if (many == null) { - // ALog.w(TAG, "保存关联数据失败,@Many注解的字段为null"); - // return; - // } - // List oneFields = CommonUtil.getAllFields(one.getClass()); - // one.save(); - // if (many.getClass() == List.class) { - // for (DbEntity sub : (List) many) { - // sub.getClass().getA - // sub.save(); - // } - // } else { - // if (DbEntity.class.isInstance(many)) { - // ((DbEntity) many).save(); - // } else { - // ALog.w(TAG, "保存关联数据失败,@Many注解的字段不是DbEntity子类"); - // return; - // } - // } - // } catch (IllegalAccessException e) { - // e.printStackTrace(); - // } - //} - - /** + /** * 删除某条数据 */ synchronized void delData(SQLiteDatabase db, Class clazz, @@ -252,9 +208,7 @@ class DelegateUpdate extends AbsDelegate { if (SqlUtil.isPrimary(field)) { //忽略自动增长的主键 Primary p = field.getAnnotation(Primary.class); - if (p.autoincrement()) { - return true; - } + return p.autoincrement(); } return false; diff --git a/Aria/src/main/java/com/arialyy/aria/orm/DelegateWrapper.java b/Aria/src/main/java/com/arialyy/aria/orm/DelegateWrapper.java index 9aaf1d3a..9209c202 100644 --- a/Aria/src/main/java/com/arialyy/aria/orm/DelegateWrapper.java +++ b/Aria/src/main/java/com/arialyy/aria/orm/DelegateWrapper.java @@ -64,6 +64,17 @@ public class DelegateWrapper { return mDManager.getDelegate(DelegateFind.class).findRelationData(mDb, clazz, expression); } + /** + * 查询关联表数据 + * + * @param expression 查询条件 + */ + List findRelationData(Class clazz, int page, int num, + String... expression) { + return mDManager.getDelegate(DelegateFind.class) + .findRelationData(mDb, clazz, page, num, expression); + } + /** * 检查某个字段的值是否存在 * diff --git a/Aria/src/main/java/com/arialyy/aria/orm/SqlHelper.java b/Aria/src/main/java/com/arialyy/aria/orm/SqlHelper.java index d9448e25..4d042fac 100644 --- a/Aria/src/main/java/com/arialyy/aria/orm/SqlHelper.java +++ b/Aria/src/main/java/com/arialyy/aria/orm/SqlHelper.java @@ -25,6 +25,8 @@ import com.arialyy.aria.core.download.DTaskWrapper; import com.arialyy.aria.core.download.DownloadEntity; import com.arialyy.aria.util.ALog; import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -80,23 +82,29 @@ final class SqlHelper extends SQLiteOpenHelper { if (oldVersion < newVersion) { if (oldVersion < 31) { handle314AriaUpdate(db); + } else if (oldVersion < 45) { + handle360AriaUpdate(db); } else { - handleDbUpdate(db); + handleDbUpdate(db, null, null); } } } @Override public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) { - //super.onDowngrade(db, oldVersion, newVersion); if (oldVersion > newVersion) { - handleDbUpdate(db); + handleDbUpdate(db, null, null); } } /** - * 处理数据库升级 + * 处理数据库升级,该段代码无法修改表字段 + * + * @param modifyColumns 需要修改的表字段的映射,key为表名, + * value{@code Map}中的Map的key为老字段名称,value为该老字段对应的新字段名称 + * @param delColumns 需要删除的表字段,key为表名,value{@code List}为需要删除的字段列表 */ - private void handleDbUpdate(SQLiteDatabase db) { + private void handleDbUpdate(SQLiteDatabase db, Map> modifyColumns, + Map> delColumns) { if (db == null) { ALog.e("SqlHelper", "db 为 null"); return; @@ -104,128 +112,152 @@ final class SqlHelper extends SQLiteOpenHelper { ALog.e("SqlHelper", "db已关闭"); return; } - Set tables = DBConfig.mapping.keySet(); - for (String tableName : tables) { - Class clazz = DBConfig.mapping.get(tableName); - if (mDelegate.tableExists(db, clazz)) { - String countColumnSql = "SELECT rowid FROM " + tableName; - Cursor cursor = db.rawQuery(countColumnSql, null); - int dbColumnNum = cursor.getColumnCount(); - List fields = SqlUtil.getAllNotIgnoreField(clazz); - int newEntityColumnNum = (fields == null || fields.isEmpty()) ? 0 : fields.size(); - if (dbColumnNum != newEntityColumnNum) { + + try { + db.beginTransaction(); + Set tables = DBConfig.mapping.keySet(); + for (String tableName : tables) { + Class clazz = DBConfig.mapping.get(tableName); + if (mDelegate.tableExists(db, clazz)) { db = mDelegate.checkDb(db); - //备份数据 - List list = - DelegateManager.getInstance().getDelegate(DelegateFind.class).findAllData(db, clazz); //修改表名为中介表名 - String alertSql = "ALTER TABLE " + tableName + " RENAME TO " + tableName + "_temp"; - //db.beginTransaction(); + String alertSql = String.format("ALTER TABLE %s RENAME TO %s_temp", tableName, tableName); db.execSQL(alertSql); - //创建一个原本的表 + //创建新表 mDelegate.createTable(db, clazz); - //传入原来的数据 - if (list != null && list.size() > 0) { - DelegateUpdate update = DelegateManager.getInstance().getDelegate(DelegateUpdate.class); - for (DbEntity entity : list) { - update.insertData(db, entity); + + String sql = String.format("SELECT COUNT(*) FROM %s_temp", tableName); + Cursor cursor = db.rawQuery(sql, null); + cursor.moveToFirst(); + long count = cursor.getLong(0); + cursor.close(); + + if (count > 0) { + // 获取所有表字段名称 + Cursor columnC = + db.rawQuery(String.format("PRAGMA table_info(%s_temp)", tableName), null); + StringBuilder params = new StringBuilder(); + + while (columnC.moveToNext()) { + String columnName = columnC.getString(columnC.getColumnIndex("name")); + if (delColumns != null && delColumns.get(tableName) != null) { + List delColumn = delColumns.get(tableName); + if (delColumn != null && !delColumn.isEmpty()) { + if (delColumn.contains(columnName)) { + continue; + } + } + } + + params.append(columnName).append(","); } + columnC.close(); + + String oldParamStr = params.toString(); + oldParamStr = oldParamStr.substring(0, oldParamStr.length() - 1); + String newParamStr = oldParamStr; + // 处理字段名称改变 + if (modifyColumns != null) { + //newParamStr = params.toString(); + Map columnMap = modifyColumns.get(tableName); + if (columnMap != null && !columnMap.isEmpty()) { + Set keys = columnMap.keySet(); + for (String key : keys) { + if (newParamStr.contains(key)) { + newParamStr = newParamStr.replace(key, columnMap.get(key)); + } + } + } + } + //恢复数据 + String insertSql = + String.format("INSERT INTO %s (%s) SELECT %s FROM %s_temp", tableName, newParamStr, + oldParamStr, tableName); + ALog.d(TAG, "insertSql = " + insertSql); + db.execSQL(insertSql); } //删除中介表 mDelegate.dropTable(db, tableName + "_temp"); } } + db.setTransactionSuccessful(); + } catch (Exception e) { + ALog.e(TAG, e); + } finally { + db.endTransaction(); } - //db.setTransactionSuccessful(); - //db.endTransaction(); + mDelegate.close(db); } + /** + * 处理3.6以下版本的数据库升级 + */ + private void handle360AriaUpdate(SQLiteDatabase db) { + String[] taskTables = + new String[] { "UploadTaskEntity", "DownloadTaskEntity", "DownloadGroupTaskEntity" }; + for (String taskTable : taskTables) { + if (mDelegate.tableExists(db, taskTable)) { + mDelegate.dropTable(db, taskTable); + } + } + Map> columnMap = new HashMap<>(); + Map map = new HashMap<>(); + map.put("groupName", "groupHash"); + columnMap.put("DownloadEntity", map); + columnMap.put("DownloadGroupEntity", map); + handleDbUpdate(db, columnMap, null); + } + /** * 处理3.4版本之前数据库迁移,主要是修改子表外键字段对应的值 */ private void handle314AriaUpdate(SQLiteDatabase db) { - Set tables = DBConfig.mapping.keySet(); - Map> map = new HashMap<>(); - for (String tableName : tables) { - Class clazz = DBConfig.mapping.get(tableName); - - String pColumn = SqlUtil.getPrimaryName(clazz); - if (!TextUtils.isEmpty(pColumn)) { - //删除所有主键为null的数据 - String nullSql = - "DELETE FROM " + tableName + " WHERE " + pColumn + " = '' OR " + pColumn + " IS NULL"; - ALog.d(TAG, nullSql); - db.execSQL(nullSql); - - //删除所有主键重复的数据 - String repeatSql = "DELETE FROM " - + tableName - + " WHERE " - + pColumn - + " in (SELECT " - + pColumn - + " FROM " - + tableName - + " GROUP BY " + pColumn + " having count(" + pColumn + ") > 1)"; - - ALog.d(TAG, repeatSql); - db.execSQL(repeatSql); + String[] taskTables = + new String[] { "UploadTaskEntity", "DownloadTaskEntity", "DownloadGroupTaskEntity" }; + for (String taskTable : taskTables) { + if (mDelegate.tableExists(db, taskTable)) { + mDelegate.dropTable(db, taskTable); } + } - //备份数据 - List list = - DelegateManager.getInstance().getDelegate(DelegateFind.class).findAllData(db, clazz); - - map.put(tableName, list); - - //修改表名为中介表名 - String alertSql = "ALTER TABLE " + tableName + " RENAME TO " + tableName + "_temp"; - db.execSQL(alertSql); - - //创建一个原本的表 - mDelegate.createTable(db, clazz); - //插入数据,3.6版本后移除任务实体的保存 - //if (list != null && list.size() > 0) { - // DelegateUpdate update = DelegateManager.getInstance().getDelegate(DelegateUpdate.class); - // try { - // for (DbEntity entity : list) { - // if (entity instanceof DTaskWrapper && ((DTaskWrapper) entity).isGroupTask()) { - // if (TextUtils.isEmpty(((DTaskWrapper) entity).getKey())) { - // ALog.w(TAG, "DownloadTaskEntity的key为空,将忽略该条数据"); - // continue; - // } - // if (TextUtils.isEmpty(((DTaskWrapper) entity).getUrl())) { - // List temp = map.get("DownloadEntity"); - // boolean isRefresh = false; - // for (DbEntity dbEntity : temp) { - // if (((DownloadEntity) dbEntity).getDownloadPath() - // .equals(((DTaskWrapper) entity).getKey())) { - // ((DTaskWrapper) entity).setUrl(((DownloadEntity) dbEntity).getUrl()); - // isRefresh = true; - // break; - // } - // } - // if (isRefresh) { - // update.insertData(db, entity); - // } - // } - // } else { - // update.insertData(db, entity); - // } - // } - // } catch (Exception e) { - // ALog.e(TAG, ALog.getExceptionString(e)); - // } - //} - - //删除中介表 - mDelegate.dropTable(db, tableName + "_temp"); - - mDelegate.close(db); + //删除所有主键为null和逐渐重复的数据 + String[] tables = new String[] { "DownloadEntity", "DownloadGroupEntity" }; + String[] keys = new String[] { "downloadPath", "groupName" }; + int i = 0; + for (String tableName : tables) { + String pColumn = keys[i]; + String nullSql = + String.format("DELETE FROM %s WHERE %s='' OR %s IS NULL", tableName, pColumn, pColumn); + ALog.d(TAG, nullSql); + db.execSQL(nullSql); + + //删除所有主键重复的数据 + String repeatSql = + String.format( + "DELETE FROM %s WHERE %s IN(SELECT %s FROM %s GROUP BY %s HAVING COUNT(%s) > 1)", + tableName, pColumn, pColumn, tableName, pColumn, pColumn); + + ALog.d(TAG, repeatSql); + db.execSQL(repeatSql); + i++; } - map.clear(); + Map> modifyColumnMap = new HashMap<>(); + Map map = new HashMap<>(); + map.put("groupName", "groupHash"); + modifyColumnMap.put("DownloadEntity", map); + modifyColumnMap.put("DownloadGroupEntity", map); + + Map> delColumnMap = new HashMap<>(); + List dEntityDel = new ArrayList<>(); + dEntityDel.add("taskKey"); + delColumnMap.put("DownloadEntity", dEntityDel); + List dgEntityDel = new ArrayList<>(); + dgEntityDel.add("subtask"); + delColumnMap.put("DownloadGroupEntity", dgEntityDel); + + handleDbUpdate(db, modifyColumnMap, delColumnMap); } } \ No newline at end of file diff --git a/DEV_LOG.md b/DEV_LOG.md index 760ce1ff..f943ce76 100644 --- a/DEV_LOG.md +++ b/DEV_LOG.md @@ -2,6 +2,7 @@ + v_3.6.2 - fix bug https://github.com/AriaLyy/Aria/issues/368 - 增加gradle 5.0支持 + - fix bug https://github.com/AriaLyy/Aria/issues/374 + v_3.6.1 (2019/3/5) - fix bug https://github.com/AriaLyy/Aria/issues/367 + v_3.6 (2019/2/27) diff --git a/app/build.gradle b/app/build.gradle index 14371df2..cad8130d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -48,9 +48,11 @@ dependencies { implementation "com.android.support:design:${rootProject.ext.supportLibVersion}" api project(':Aria') annotationProcessor project(':AriaCompiler') - // compile 'com.arialyy.aria:aria-core:3.3.16' - // annotationProcessor 'com.arialyy.aria:aria-compiler:3.3.16' - debugApi 'com.amitshekhar.android:debug-db:1.0.0' + // compile 'com.arialyy.aria:aria-core:3.4.0' + // annotationProcessor 'com.arialyy.aria:aria-compiler:3.4' + + // compile 'com.arialyy.aria:aria-core:3.3.14' + // annotationProcessor 'com.arialyy.aria:aria-compiler:3.3.14' api 'com.github.PhilJay:MPAndroidChart:v3.0.3' implementation project(':AppFrame') }