laoyuyu 6 years ago
parent 9ff9e1e5dd
commit c604eda465
  1. 11
      Aria/src/main/java/com/arialyy/aria/core/AriaManager.java
  2. 32
      Aria/src/main/java/com/arialyy/aria/core/common/ftp/FTPSDelegate.java
  3. 2
      Aria/src/main/java/com/arialyy/aria/core/common/http/GetDelegate.java
  4. 30
      Aria/src/main/java/com/arialyy/aria/core/common/http/HttpDelegate.java
  5. 2
      Aria/src/main/java/com/arialyy/aria/core/common/http/PostDelegate.java
  6. 31
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadReceiver.java
  7. 2
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadTarget.java
  8. 8
      Aria/src/main/java/com/arialyy/aria/core/download/FtpDirDownloadTarget.java
  9. 9
      Aria/src/main/java/com/arialyy/aria/core/download/FtpDownloadTarget.java
  10. 17
      Aria/src/main/java/com/arialyy/aria/core/inf/AbsTarget.java
  11. 23
      Aria/src/main/java/com/arialyy/aria/core/inf/ITarget.java
  12. 8
      Aria/src/main/java/com/arialyy/aria/core/upload/FtpUploadTarget.java
  13. 14
      Aria/src/main/java/com/arialyy/aria/core/upload/UploadReceiver.java
  14. 6
      Aria/src/main/java/com/arialyy/aria/orm/AbsDelegate.java
  15. 2
      Aria/src/main/java/com/arialyy/aria/orm/DBConfig.java
  16. 42
      Aria/src/main/java/com/arialyy/aria/orm/DbEntity.java
  17. 13
      Aria/src/main/java/com/arialyy/aria/orm/DelegateCommon.java
  18. 165
      Aria/src/main/java/com/arialyy/aria/orm/DelegateFind.java
  19. 50
      Aria/src/main/java/com/arialyy/aria/orm/DelegateUpdate.java
  20. 11
      Aria/src/main/java/com/arialyy/aria/orm/DelegateWrapper.java
  21. 242
      Aria/src/main/java/com/arialyy/aria/orm/SqlHelper.java
  22. 1
      DEV_LOG.md
  23. 8
      app/build.gradle

@ -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();

@ -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<TARGET extends AbsTarget> implements ITarget {
private final String TAG = "FTPSConfig";
public class FTPSDelegate<TARGET extends AbsTarget> 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<TARGET extends AbsTarget> 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<TARGET extends AbsTarget> 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<TARGET extends AbsTarget> 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<TARGET extends AbsTarget> 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<TARGET extends AbsTarget> 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();
}
}

@ -21,7 +21,7 @@ import com.arialyy.aria.core.inf.AbsTarget;
/**
* get处理委托类
*/
public class GetDelegate<TARGET extends AbsTarget> extends BaseTarget<TARGET> {
public class GetDelegate<TARGET extends AbsTarget> extends HttpDelegate<TARGET> {
public GetDelegate(TARGET target) {
super(target);

@ -25,11 +25,15 @@ import com.arialyy.aria.util.ALog;
import java.util.HashMap;
import java.util.Map;
class BaseTarget<TARGET extends AbsTarget> implements ITarget {
/**
* HTTP参数委托
* @param <TARGET>
*/
class HttpDelegate<TARGET extends AbsTarget> 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<TARGET extends AbsTarget> 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();
}
}

@ -21,7 +21,7 @@ import com.arialyy.aria.core.inf.AbsTarget;
/**
* post处理委托类
*/
public class PostDelegate<TARGET extends AbsTarget> extends BaseTarget<TARGET> {
public class PostDelegate<TARGET extends AbsTarget> extends HttpDelegate<TARGET> {
public PostDelegate(TARGET target) {
super(target);

@ -322,12 +322,13 @@ public class DownloadReceiver extends AbsReceiver {
}
/**
* 分页获取所有普通下载任务如果页数大于总页数返回null
* 分页获取所有普通下载任务
* 获取未完成的普通任务列表{@link #getAllNotCompleteTask()}
* 获取已经完成的普通任务列表{@link #getAllCompleteTask()}
*
* @param page 当前页不能小于1
* @param num 每页数量不能小于1
* @return 如果页数大于总页数返回null
*/
public List<DownloadEntity> 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<DownloadEntity> 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<DownloadEntity> 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<DownloadGroupEntity> getGroupTaskList(int page, int num) {
List<DGEntityWrapper> wrappers = DbEntity.findRelationData(DGEntityWrapper.class, page, num);
if (wrappers == null || wrappers.isEmpty()) {
return null;
}
List<DownloadGroupEntity> entities = new ArrayList<>();
for (DGEntityWrapper wrapper : wrappers) {
entities.add(wrapper.groupEntity);
}
return entities;
}
/**
* 获取普通任务和任务组的任务列表
*/

@ -44,6 +44,7 @@ public class DownloadTarget extends BaseNormalTarget<DownloadTarget>
/**
* Post处理
*/
@CheckResult
public PostDelegate asPost() {
return new PostDelegate<>(this);
}
@ -51,6 +52,7 @@ public class DownloadTarget extends BaseNormalTarget<DownloadTarget>
/**
* get参数传递
*/
@CheckResult
public GetDelegate asGet(){
return new GetDelegate<>(this);
}

@ -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<FtpDirDownloadTarget>
/**
* 是否是FTPS协议
* 如果是FTPS协议需要使用{@link FTPSConfig#setStorePath(String)} {@link FTPSConfig#setAlias(String)}
* 如果是FTPS协议需要使用{@link FTPSDelegate#setStorePath(String)} {@link FTPSDelegate#setAlias(String)}
* 设置证书信息
*/
@CheckResult
public FTPSConfig<FtpDirDownloadTarget> asFtps() {
public FTPSDelegate<FtpDirDownloadTarget> asFtps() {
mTaskWrapper.asFtp().getUrlEntity().isFtps = true;
return new FTPSConfig<>(this);
return new FTPSDelegate<>(this);
}
@CheckResult

@ -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<FtpDownloadTarget>
/**
* 是否是FTPS协议
* 如果是FTPS协议需要使用{@link FTPSConfig#setStorePath(String)} {@link FTPSConfig#setAlias(String)}
* 如果是FTPS协议需要使用{@link FTPSDelegate#setStorePath(String)} {@link FTPSDelegate#setAlias(String)}
* 设置证书信息
*/
@CheckResult
public FTPSConfig<FtpDownloadTarget> asFtps() {
public FTPSDelegate<FtpDownloadTarget> asFtps() {
mTaskWrapper.asFtp().getUrlEntity().isFtps = true;
return new FTPSConfig<>(this);
return new FTPSDelegate<>(this);
}
@Override protected boolean checkEntity() {

@ -190,13 +190,12 @@ public abstract class AbsTarget<TARGET extends AbsTarget, ENTITY extends AbsEnti
/**
* 保存修改
*/
public void save() {
@Override public void save() {
if (!checkEntity()) {
ALog.e(TAG, "保存修改失败");
}else {
} else {
ALog.i(TAG, "保存成功");
}
}
/**
@ -220,7 +219,8 @@ public abstract class AbsTarget<TARGET extends AbsTarget, ENTITY extends AbsEnti
if (checkEntity()) {
AriaManager.getInstance(AriaManager.APP)
.setCmd(
CommonUtil.createNormalCmd(mTaskWrapper, NormalCmdFactory.TASK_START, checkTaskType()))
CommonUtil.createNormalCmd(mTaskWrapper, NormalCmdFactory.TASK_START,
checkTaskType()))
.exe();
}
}
@ -252,7 +252,8 @@ public abstract class AbsTarget<TARGET extends AbsTarget, ENTITY extends AbsEnti
if (checkEntity()) {
AriaManager.getInstance(AriaManager.APP)
.setCmd(
CommonUtil.createNormalCmd(mTaskWrapper, NormalCmdFactory.TASK_START, checkTaskType()))
CommonUtil.createNormalCmd(mTaskWrapper, NormalCmdFactory.TASK_START,
checkTaskType()))
.exe();
}
}
@ -272,7 +273,7 @@ public abstract class AbsTarget<TARGET extends AbsTarget, ENTITY extends AbsEnti
/**
* 任务重试
*/
public void reTry() {
@Override public void reTry() {
if (checkEntity()) {
List<ICmd> cmds = new ArrayList<>();
int taskType = checkTaskType();
@ -289,7 +290,7 @@ public abstract class AbsTarget<TARGET extends AbsTarget, ENTITY extends AbsEnti
* @param removeFile {@code true} 不仅删除任务数据库记录还会删除已经删除完成的文件
* {@code false}如果任务已经完成只删除任务数据库记录
*/
public void cancel(boolean removeFile) {
@Override public void cancel(boolean removeFile) {
if (checkEntity()) {
CancelCmd cancelCmd =
(CancelCmd) CommonUtil.createNormalCmd(mTaskWrapper, NormalCmdFactory.TASK_CANCEL,
@ -302,7 +303,7 @@ public abstract class AbsTarget<TARGET extends AbsTarget, ENTITY extends AbsEnti
/**
* 重新下载
*/
public void reStart() {
@Override public void reStart() {
if (checkEntity()) {
cancel();
start();

@ -38,4 +38,27 @@ public interface ITarget {
* 取消下载
*/
void cancel();
/**
* 保存修改
*/
void save();
/**
* 删除任务
*
* @param removeFile {@code true} 不仅删除任务数据库记录还会删除已经删除完成的文件
* {@code false}如果任务已经完成只删除任务数据库记录
*/
void cancel(boolean removeFile);
/**
* 任务重试
*/
void reTry();
/**
* 重新下载
*/
void reStart();
}

@ -19,7 +19,7 @@ import android.support.annotation.CheckResult;
import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.FtpUrlEntity;
import com.arialyy.aria.core.command.normal.NormalCmdFactory;
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;
@ -86,17 +86,17 @@ public class FtpUploadTarget extends BaseNormalTarget<FtpUploadTarget>
/**
* 是否是FTPS协议
* 如果是FTPS协议需要使用{@link FTPSConfig#setStorePath(String)} {@link FTPSConfig#setAlias(String)}
* 如果是FTPS协议需要使用{@link FTPSDelegate#setStorePath(String)} {@link FTPSDelegate#setAlias(String)}
* 设置证书信息
*/
@CheckResult
public FTPSConfig<FtpUploadTarget> asFtps() {
public FTPSDelegate<FtpUploadTarget> 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

@ -106,12 +106,13 @@ public class UploadReceiver extends AbsReceiver {
}
/**
* 分页获取所有普通上传任务如果页数大于总页数返回null
* 分页获取所有普通上传任务
* 获取未完成的普通任务列表{@link #getAllNotCompleteTask()}
* 获取已经完成的普通任务列表{@link #getAllCompleteTask()}
*
* @param page 当前页不能小于1
* @param num 每页数量不能小于1
* @return 如果页数大于总页数返回null
*/
public List<UploadEntity> 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<UploadEntity> getAllNotCompleteTask(int page, int num) {
CheckUtil.checkPageParams(page, num);
@ -140,7 +142,7 @@ public class UploadReceiver extends AbsReceiver {
}
/**
* 获取所有已经完成的普通任务如果页数大于总页数返回null
* 获取所有已经完成的普通任务
*/
public List<UploadEntity> 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<UploadEntity> getAllCompleteTask(int page, int num) {
CheckUtil.checkPageParams(page, num);

@ -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 >>> ";

@ -35,7 +35,7 @@ class DBConfig {
/*adb pull /mnt/sdcard/Android/data/com.arialyy.simple/files/DB/AriaLyyDb d:/db*/
static Map<String, Class> mapping = new HashMap<>();
static String DB_NAME;
static int VERSION = 44;
static int VERSION = 45;
/**
* 是否将数据库保存在Sd卡{@code true}

@ -30,15 +30,11 @@ public abstract class DbEntity {
}
///**
// * 保存关联数据
// */
//public static void saveRelationData(AbsDbWrapper wrapper) {
// DelegateWrapper.getInstance().saveRelationData(wrapper);
//}
/**
* 查询关联数据
* <code>
* DbEntity.findRelationData(DGEntityWrapper.class, "downloadUrl=?", downloadUrl);
* </code>
*
* @param expression 查询条件
*/
@ -47,6 +43,26 @@ public abstract class DbEntity {
return DelegateWrapper.getInstance().findRelationData(clazz, expression);
}
/**
* 分页查询关联数据
*
* <code>
* DbEntity.findRelationData(DGEntityWrapper.class, 0, 10, "downloadUrl=?", downloadUrl);
* </code>
*
* @param expression 查询条件
* @param page 需要查询的页数从1开始如果page小于1 num 小于1返回null
* @param num 每页返回的数量
* @return 没有数据返回null如果页数大于总页数返回null
*/
public static <T extends AbsDbWrapper> List<T> findRelationData(Class<T> 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 {
/**
* 查询一组数据
* <code>
* DownloadEntity.findFirst(DownloadEntity.class, "downloadUrl=?", downloadUrl);
* DbEntity.findFirst(DownloadEntity.class, "downloadUrl=?", downloadUrl);
* </code>
*
* @return 没有数据返回null
@ -103,7 +119,7 @@ public abstract class DbEntity {
/**
* 分页查询数据
* <code>
* DownloadEntity.findFirst(DownloadEntity.class, 0, 10, "downloadUrl=?", downloadUrl);
* DbEntity.findFirst(DownloadEntity.class, 0, 10, "downloadUrl=?", downloadUrl);
* </code>
*
* @param page 需要查询的页数从1开始如果page小于1 num 小于1返回null
@ -121,7 +137,7 @@ public abstract class DbEntity {
/**
* 模糊查询一组数据
* <code>
* DownloadEntity.findDatas(DownloadEntity.class, "downloadUrl like http://");
* DbEntity.findDataByFuzzy(DownloadEntity.class, "downloadUrl like http://");
* </code>
*
* @return 没有数据返回null
@ -133,7 +149,7 @@ public abstract class DbEntity {
/**
* 模糊查询一组数据
* <code>
* DownloadEntity.findDatas(DownloadEntity.class, "downloadUrl like http://");
* DbEntity.findDataByFuzzy(DownloadEntity.class, 0, 10, "downloadUrl like http://");
* </code>
*
* @param page 需要查询的页数从1开始如果page小于1 num 小于1返回null
@ -148,7 +164,7 @@ public abstract class DbEntity {
/**
* 查询一行数据
* <code>
* DownloadEntity.findFirst(DownloadEntity.class, "downloadUrl=?", downloadUrl);
* DbEntity.findFirst(DownloadEntity.class, "downloadUrl=?", downloadUrl);
* </code>
*
* @return 没有数据返回null
@ -220,7 +236,7 @@ public abstract class DbEntity {
/**
* 根据条件删除数据
* <code>
* DownloadEntity.deleteData(DownloadEntity.class, "downloadUrl=?", downloadUrl);
* DbEntity.deleteData(DownloadEntity.class, "downloadUrl=?", downloadUrl);
* </code>
*/
public static <T extends DbEntity> void deleteData(Class<T> clazz, String... expression) {

@ -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++) {

@ -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 {
*/
<T extends AbsDbWrapper> List<T> findRelationData(SQLiteDatabase db, Class<T> 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}
*/
<T extends AbsDbWrapper> List<T> findRelationData(SQLiteDatabase db, Class<T> 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 <T extends AbsDbWrapper> List<T> exeRelationSql(SQLiteDatabase db, Class<T> 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<T> 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<T> 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<T> 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<T> 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<T> 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 {
*/
<T extends DbEntity> List<T> findAllData(SQLiteDatabase db, Class<T> 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 <T extends DbEntity> List<T> exeNormalDataSql(SQLiteDatabase db, Class<T> clazz,
String sql, String[] selectionArgs) {
print(FIND_DATA, sql);
Cursor cursor = db.rawQuery(sql, selectionArgs);
List<T> data = cursor.getCount() > 0 ? newInstanceEntity(clazz, cursor) : null;
closeCursor(cursor);
close(db);

@ -34,51 +34,7 @@ class DelegateUpdate extends AbsDelegate {
private DelegateUpdate() {
}
///**
// * 添加或更新关联数据
// */
//void saveRelationData(SQLiteDatabase db, AbsDbWrapper wrapper) {
// Class clazz = wrapper.getClass();
// List<Field> 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<Field> oneFields = CommonUtil.getAllFields(one.getClass());
// one.save();
// if (many.getClass() == List.class) {
// for (DbEntity sub : (List<DbEntity>) 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 <T extends DbEntity> void delData(SQLiteDatabase db, Class<T> 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;

@ -64,6 +64,17 @@ public class DelegateWrapper {
return mDManager.getDelegate(DelegateFind.class).findRelationData(mDb, clazz, expression);
}
/**
* 查询关联表数据
*
* @param expression 查询条件
*/
<T extends AbsDbWrapper> List<T> findRelationData(Class<T> clazz, int page, int num,
String... expression) {
return mDManager.getDelegate(DelegateFind.class)
.findRelationData(mDb, clazz, page, num, expression);
}
/**
* 检查某个字段的值是否存在
*

@ -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<String, String>}中的Map的key为老字段名称value为该老字段对应的新字段名称
* @param delColumns 需要删除的表字段key为表名value{@code List<String>}为需要删除的字段列表
*/
private void handleDbUpdate(SQLiteDatabase db) {
private void handleDbUpdate(SQLiteDatabase db, Map<String, Map<String, String>> modifyColumns,
Map<String, List<String>> 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<String> 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<Field> fields = SqlUtil.getAllNotIgnoreField(clazz);
int newEntityColumnNum = (fields == null || fields.isEmpty()) ? 0 : fields.size();
if (dbColumnNum != newEntityColumnNum) {
try {
db.beginTransaction();
Set<String> tables = DBConfig.mapping.keySet();
for (String tableName : tables) {
Class clazz = DBConfig.mapping.get(tableName);
if (mDelegate.tableExists(db, clazz)) {
db = mDelegate.checkDb(db);
//备份数据
List<DbEntity> 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<String> 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<String, String> columnMap = modifyColumns.get(tableName);
if (columnMap != null && !columnMap.isEmpty()) {
Set<String> 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<String, Map<String, String>> columnMap = new HashMap<>();
Map<String, String> 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<String> tables = DBConfig.mapping.keySet();
Map<String, List<DbEntity>> 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<DbEntity> 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<DbEntity> 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<String, Map<String, String>> modifyColumnMap = new HashMap<>();
Map<String, String> map = new HashMap<>();
map.put("groupName", "groupHash");
modifyColumnMap.put("DownloadEntity", map);
modifyColumnMap.put("DownloadGroupEntity", map);
Map<String, List<String>> delColumnMap = new HashMap<>();
List<String> dEntityDel = new ArrayList<>();
dEntityDel.add("taskKey");
delColumnMap.put("DownloadEntity", dEntityDel);
List<String> dgEntityDel = new ArrayList<>();
dgEntityDel.add("subtask");
delColumnMap.put("DownloadGroupEntity", dgEntityDel);
handleDbUpdate(db, modifyColumnMap, delColumnMap);
}
}

@ -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)

@ -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')
}

Loading…
Cancel
Save