From 178061475ea612459fbd78cdd2a9bfbe81fa88eb Mon Sep 17 00:00:00 2001 From: Alinson S Xavier Date: Sat, 8 Dec 2018 12:24:44 -0600 Subject: [PATCH] Improve performance when importing database --- .../isoron/uhabits/tasks/ImportDataTask.java | 13 ++- .../uhabits/core/database/Repository.java | 88 ++++++++++++++----- .../core/models/sqlite/SQLModelFactory.java | 2 +- 3 files changed, 77 insertions(+), 26 deletions(-) diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/tasks/ImportDataTask.java b/uhabits-android/src/main/java/org/isoron/uhabits/tasks/ImportDataTask.java index caec0f823..52e536955 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/tasks/ImportDataTask.java +++ b/uhabits-android/src/main/java/org/isoron/uhabits/tasks/ImportDataTask.java @@ -24,6 +24,8 @@ import android.support.annotation.*; import com.google.auto.factory.*; import org.isoron.uhabits.core.io.*; +import org.isoron.uhabits.core.models.ModelFactory; +import org.isoron.uhabits.core.models.sqlite.SQLModelFactory; import org.isoron.uhabits.core.tasks.*; import java.io.*; @@ -37,21 +39,25 @@ public class ImportDataTask implements Task public static final int SUCCESS = 1; - int result; + private int result; @NonNull private final File file; private GenericImporter importer; + private SQLModelFactory modelFactory; + @NonNull private final Listener listener; public ImportDataTask(@Provided @NonNull GenericImporter importer, + @Provided @NonNull ModelFactory modelFactory, @NonNull File file, @NonNull Listener listener) { this.importer = importer; + this.modelFactory = (SQLModelFactory) modelFactory; this.listener = listener; this.file = file; } @@ -59,12 +65,15 @@ public class ImportDataTask implements Task @Override public void doInBackground() { + modelFactory.db.beginTransaction(); + try { if (importer.canHandle(file)) { importer.importHabitsFromFile(file); result = SUCCESS; + modelFactory.db.setTransactionSuccessful(); } else { @@ -76,6 +85,8 @@ public class ImportDataTask implements Task result = FAILED; e.printStackTrace(); } + + modelFactory.db.endTransaction(); } @Override diff --git a/uhabits-core/src/main/java/org/isoron/uhabits/core/database/Repository.java b/uhabits-core/src/main/java/org/isoron/uhabits/core/database/Repository.java index 01f94a6f7..5bff771d9 100644 --- a/uhabits-core/src/main/java/org/isoron/uhabits/core/database/Repository.java +++ b/uhabits-core/src/main/java/org/isoron/uhabits/core/database/Repository.java @@ -246,56 +246,96 @@ public class Repository return fields; } + private Field[] cacheFields = null; + @NonNull private Field[] getFields() { - List fields = new ArrayList<>(); - List> columns = getFieldColumnPairs(); - for (Pair pair : columns) fields.add(pair.getLeft()); - return fields.toArray(new Field[]{}); + if (cacheFields == null) + { + List fields = new ArrayList<>(); + List> columns = getFieldColumnPairs(); + for (Pair pair : columns) fields.add(pair.getLeft()); + cacheFields = fields.toArray(new Field[]{}); + } + + return cacheFields; } + private String[] cacheColumnNames = null; + @NonNull private String[] getColumnNames() { - List names = new ArrayList<>(); - List> columns = getFieldColumnPairs(); - for (Pair pair : columns) + if (cacheColumnNames == null) { - String cname = pair.getRight().name(); - if (cname.isEmpty()) cname = pair.getLeft().getName(); - if (names.contains(cname)) - throw new RuntimeException("duplicated column : " + cname); - names.add(cname); + List names = new ArrayList<>(); + List> columns = getFieldColumnPairs(); + for (Pair pair : columns) + { + String cname = pair.getRight().name(); + if (cname.isEmpty()) cname = pair.getLeft().getName(); + if (names.contains(cname)) + throw new RuntimeException("duplicated column : " + cname); + names.add(cname); + } + + cacheColumnNames = names.toArray(new String[]{}); } - return names.toArray(new String[]{}); + return cacheColumnNames; } + private String cacheTableName = null; + @NonNull private String getTableName() { - String name = getTableAnnotation().name(); - if (name.isEmpty()) throw new RuntimeException("Table name is empty"); - return name; + if (cacheTableName == null) + { + String name = getTableAnnotation().name(); + if (name.isEmpty()) throw new RuntimeException("Table name is empty"); + cacheTableName = name; + } + return cacheTableName; } + private String cacheIdName = null; + @NonNull private String getIdName() { - String id = getTableAnnotation().id(); - if (id.isEmpty()) throw new RuntimeException("Table id is empty"); - return id; + if (cacheIdName == null) + { + String id = getTableAnnotation().id(); + if (id.isEmpty()) throw new RuntimeException("Table id is empty"); + cacheIdName = id; + } + + return cacheIdName; } + private Field cacheIdField = null; + @NonNull private Field getIdField() { - Field fields[] = getFields(); - String idName = getIdName(); - for (Field f : fields) - if (f.getName().equals(idName)) return f; - throw new RuntimeException("Field not found: " + idName); + if (cacheIdField == null) + { + Field fields[] = getFields(); + String idName = getIdName(); + for (Field f : fields) + if (f.getName().equals(idName)) + { + cacheIdField = f; + break; + } + + if (cacheIdField == null) + throw new RuntimeException("Field not found: " + idName); + } + + return cacheIdField; } @NonNull diff --git a/uhabits-core/src/main/java/org/isoron/uhabits/core/models/sqlite/SQLModelFactory.java b/uhabits-core/src/main/java/org/isoron/uhabits/core/models/sqlite/SQLModelFactory.java index 702e8acff..55daa49e9 100644 --- a/uhabits-core/src/main/java/org/isoron/uhabits/core/models/sqlite/SQLModelFactory.java +++ b/uhabits-core/src/main/java/org/isoron/uhabits/core/models/sqlite/SQLModelFactory.java @@ -33,7 +33,7 @@ import javax.inject.*; */ public class SQLModelFactory implements ModelFactory { - private final Database db; + public final Database db; @Inject public SQLModelFactory(Database db)