diff --git a/.gitignore b/.gitignore
index 20374e4a4..b91594d1b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,4 @@
out/
build/
local.properties
+/bin/
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f1548666d..eea4cd151 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,13 +1,11 @@
Release History
---------------
-### V2.1.0 Minor feature and bugfix release (2015-11-12, both core and generator)
+### V2.1.0 Minor feature release (2015-09-XX, both core and generator)
* Official Robolectric support: workaround for a broken system call in Robolectric triggered by Query.forCurrentThread
-* QueryBuilder now allows to create DISTINCT queries to avoid duplicate entities returned
* CursorQuery (beta, API might change)
-* Deadlock prevention when loading a list of entities while doing concurrent updates
* Fixed async queries
* Better Android Studio support
-* Generator: Possibility to supply custom JavaDoc for entities and their properties
+* Added performance tests for: ActiveAndroid, Realm, Parse
* Generator: Fixed codeBeforeGetter, added codeBeforeGetterAndSetter
### V2.0.0 Major feature release (2015-07-30, both core and generator)
diff --git a/DaoCore/build.gradle b/DaoCore/build.gradle
index 4f3e7e2c5..4978cc077 100644
--- a/DaoCore/build.gradle
+++ b/DaoCore/build.gradle
@@ -4,7 +4,7 @@ apply plugin: 'signing'
group = 'de.greenrobot'
archivesBaseName = 'greendao'
-version = '2.1.0'
+version = '2.1.0-SNAPSHOT'
sourceCompatibility = 1.6
def isSnapshot = version.endsWith('-SNAPSHOT')
@@ -45,7 +45,7 @@ javadoc {
failOnError = false
classpath += configurations.provided
title = " greenDAO ${version} API"
- options.bottom = 'Available under the Apache License, Version 2.0 - Copyright © 2011-2015 greenrobot.de. All Rights Reserved.'
+ options.bottom = 'Available under the Apache License, Version 2.0 - Copyright © 2011-2013 greenrobot.de. All Rights Reserved.'
excludes = ['de/greenrobot/dao/internal','de/greenrobot/dao/Internal*']
}
diff --git a/DaoCore/src/main/java/de/greenrobot/dao/AbstractDao.java b/DaoCore/src/main/java/de/greenrobot/dao/AbstractDao.java
index d39b306ac..51349dfb9 100644
--- a/DaoCore/src/main/java/de/greenrobot/dao/AbstractDao.java
+++ b/DaoCore/src/main/java/de/greenrobot/dao/AbstractDao.java
@@ -16,19 +16,17 @@
package de.greenrobot.dao;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
import android.database.CrossProcessCursor;
import android.database.Cursor;
import android.database.CursorWindow;
import android.database.DatabaseUtils;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteStatement;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
import de.greenrobot.dao.identityscope.IdentityScope;
import de.greenrobot.dao.identityscope.IdentityScopeLong;
import de.greenrobot.dao.internal.DaoConfig;
@@ -39,12 +37,15 @@
/**
* Base class for all DAOs: Implements entity operations like insert, load, delete, and query.
- *
+ *
* This class is thread-safe.
*
- * @param Entity type
- * @param Primary key (PK) type; use Void if entity does not have exactly one PK
* @author Markus
+ *
+ * @param
+ * Entity type
+ * @param
+ * Primary key (PK) type; use Void if entity does not have exactly one PK
*/
/*
* When operating on TX, statements, or identity scope the following locking order must be met to avoid deadlocks:
@@ -117,7 +118,8 @@ public String[] getNonPkColumns() {
/**
* Loads and entity for the given PK.
*
- * @param key a PK value or null
+ * @param key
+ * a PK value or null
* @return The entity or null, if no entity matched the PK value
*/
public T load(K key) {
@@ -132,13 +134,13 @@ public T load(K key) {
}
}
String sql = statements.getSelectByKey();
- String[] keyArray = new String[]{key.toString()};
+ String[] keyArray = new String[] { key.toString() };
Cursor cursor = db.rawQuery(sql, keyArray);
return loadUniqueAndCloseCursor(cursor);
}
public T loadByRowId(long rowId) {
- String[] idArray = new String[]{Long.toString(rowId)};
+ String[] idArray = new String[] { Long.toString(rowId) };
Cursor cursor = db.rawQuery(statements.getSelectByRowId(), idArray);
return loadUniqueAndCloseCursor(cursor);
}
@@ -188,7 +190,8 @@ protected List loadAllAndCloseCursor(Cursor cursor) {
/**
* Inserts the given entities in the database using a transaction.
*
- * @param entities The entities to insert.
+ * @param entities
+ * The entities to insert.
*/
public void insertInTx(Iterable entities) {
insertInTx(entities, isEntityUpdateable());
@@ -197,7 +200,8 @@ public void insertInTx(Iterable entities) {
/**
* Inserts the given entities in the database using a transaction.
*
- * @param entities The entities to insert.
+ * @param entities
+ * The entities to insert.
*/
public void insertInTx(T... entities) {
insertInTx(Arrays.asList(entities), isEntityUpdateable());
@@ -207,8 +211,10 @@ public void insertInTx(T... entities) {
* Inserts the given entities in the database using a transaction. The given entities will become tracked if the PK
* is set.
*
- * @param entities The entities to insert.
- * @param setPrimaryKey if true, the PKs of the given will be set after the insert; pass false to improve performance.
+ * @param entities
+ * The entities to insert.
+ * @param setPrimaryKey
+ * if true, the PKs of the given will be set after the insert; pass false to improve performance.
*/
public void insertInTx(Iterable entities, boolean setPrimaryKey) {
SQLiteStatement stmt = statements.getInsertStatement();
@@ -219,8 +225,10 @@ public void insertInTx(Iterable entities, boolean setPrimaryKey) {
* Inserts or replaces the given entities in the database using a transaction. The given entities will become
* tracked if the PK is set.
*
- * @param entities The entities to insert.
- * @param setPrimaryKey if true, the PKs of the given will be set after the insert; pass false to improve performance.
+ * @param entities
+ * The entities to insert.
+ * @param setPrimaryKey
+ * if true, the PKs of the given will be set after the insert; pass false to improve performance.
*/
public void insertOrReplaceInTx(Iterable entities, boolean setPrimaryKey) {
SQLiteStatement stmt = statements.getInsertOrReplaceStatement();
@@ -230,7 +238,8 @@ public void insertOrReplaceInTx(Iterable entities, boolean setPrimaryKey) {
/**
* Inserts or replaces the given entities in the database using a transaction.
*
- * @param entities The entities to insert.
+ * @param entities
+ * The entities to insert.
*/
public void insertOrReplaceInTx(Iterable entities) {
insertOrReplaceInTx(entities, isEntityUpdateable());
@@ -239,7 +248,8 @@ public void insertOrReplaceInTx(Iterable entities) {
/**
* Inserts or replaces the given entities in the database using a transaction.
*
- * @param entities The entities to insert.
+ * @param entities
+ * The entities to insert.
*/
public void insertOrReplaceInTx(T... entities) {
insertOrReplaceInTx(Arrays.asList(entities), isEntityUpdateable());
@@ -359,18 +369,12 @@ protected void updateKeyAfterInsertAndAttach(T entity, long rowId, boolean lock)
/** Reads all available rows from the given cursor and returns a list of entities. */
protected List loadAllFromCursor(Cursor cursor) {
int count = cursor.getCount();
- if (count == 0) {
- return Collections.EMPTY_LIST;
- }
List list = new ArrayList(count);
- CursorWindow window = null;
- boolean useFastCursor = false;
if (cursor instanceof CrossProcessCursor) {
- window = ((CrossProcessCursor) cursor).getWindow();
- if (window != null) { // E.g. Robolectric has no Window at this point
+ CursorWindow window = ((CrossProcessCursor) cursor).getWindow();
+ if (window != null) { // E.g. Roboelectric has no Window at this point
if (window.getNumRows() == count) {
cursor = new FastCursor(window);
- useFastCursor = true;
} else {
DaoLog.d("Window vs. result size: " + window.getNumRows() + "/" + count);
}
@@ -382,15 +386,10 @@ protected List loadAllFromCursor(Cursor cursor) {
identityScope.lock();
identityScope.reserveRoom(count);
}
-
try {
- if (!useFastCursor && window != null && identityScope != null) {
- loadAllUnlockOnWindowBounds(cursor, window, list);
- } else {
- do {
- list.add(loadCurrent(cursor, 0, false));
- } while (cursor.moveToNext());
- }
+ do {
+ list.add(loadCurrent(cursor, 0, false));
+ } while (cursor.moveToNext());
} finally {
if (identityScope != null) {
identityScope.unlock();
@@ -400,42 +399,6 @@ protected List loadAllFromCursor(Cursor cursor) {
return list;
}
- private void loadAllUnlockOnWindowBounds(Cursor cursor, CursorWindow window, List list) {
- int windowEnd = window.getStartPosition() + window.getNumRows();
- for (int row = 0; ; row++) {
- list.add(loadCurrent(cursor, 0, false));
- row++;
- if (row >= windowEnd) {
- window = moveToNextUnlocked(cursor);
- if(window == null) {
- break;
- }
- windowEnd = window.getStartPosition() + window.getNumRows();
- } else {
- if(!cursor.moveToNext()) {
- break;
- }
- }
- }
- }
-
- /**
- * Unlock identityScope during cursor.moveToNext() when it is about to fill the window (needs a db connection):
- * We should not hold the lock while trying to acquire a db connection to avoid deadlocks.
- */
- private CursorWindow moveToNextUnlocked(Cursor cursor) {
- identityScope.unlock();
- try {
- if(cursor.moveToNext()) {
- return ((CrossProcessCursor) cursor).getWindow();
- } else {
- return null;
- }
- } finally {
- identityScope.lock();
- }
- }
-
/** Internal use only. Considers identity scope. */
final protected T loadCurrent(Cursor cursor, int offset, boolean lock) {
if (identityScopeLong != null) {
@@ -617,7 +580,8 @@ private void deleteInTxInternal(Iterable entities, Iterable keys) {
/**
* Deletes the given entities in the database using a transaction.
*
- * @param entities The entities to delete.
+ * @param entities
+ * The entities to delete.
*/
public void deleteInTx(Iterable entities) {
deleteInTxInternal(entities, null);
@@ -626,7 +590,8 @@ public void deleteInTx(Iterable entities) {
/**
* Deletes the given entities in the database using a transaction.
*
- * @param entities The entities to delete.
+ * @param entities
+ * The entities to delete.
*/
public void deleteInTx(T... entities) {
deleteInTxInternal(Arrays.asList(entities), null);
@@ -635,7 +600,8 @@ public void deleteInTx(T... entities) {
/**
* Deletes all entities with the given keys in the database using a transaction.
*
- * @param keys Keys of the entities to delete.
+ * @param keys
+ * Keys of the entities to delete.
*/
public void deleteByKeyInTx(Iterable keys) {
deleteInTxInternal(null, keys);
@@ -644,7 +610,8 @@ public void deleteByKeyInTx(Iterable keys) {
/**
* Deletes all entities with the given keys in the database using a transaction.
*
- * @param keys Keys of the entities to delete.
+ * @param keys
+ * Keys of the entities to delete.
*/
public void deleteByKeyInTx(K... keys) {
deleteInTxInternal(null, Arrays.asList(keys));
@@ -655,7 +622,7 @@ public void refresh(T entity) {
assertSinglePk();
K key = getKeyVerified(entity);
String sql = statements.getSelectByKey();
- String[] keyArray = new String[]{key.toString()};
+ String[] keyArray = new String[] { key.toString() };
Cursor cursor = db.rawQuery(sql, keyArray);
try {
boolean available = cursor.moveToFirst();
@@ -716,9 +683,11 @@ protected void updateInsideSynchronized(T entity, SQLiteStatement stmt, boolean
/**
* Attaches the entity to the identity scope. Calls attachEntity(T entity).
*
- * @param key Needed only for identity scope, pass null if there's none.
- * @param entity The entitiy to attach
- */
+ * @param key
+ * Needed only for identity scope, pass null if there's none.
+ * @param entity
+ * The entitiy to attach
+ * */
protected final void attachEntity(K key, T entity, boolean lock) {
attachEntity(entity);
if (identityScope != null && key != null) {
@@ -734,15 +703,17 @@ protected final void attachEntity(K key, T entity, boolean lock) {
* Sub classes with relations additionally set the DaoMaster here. Must be called before the entity is attached to
* the identity scope.
*
- * @param entity The entitiy to attach
- */
+ * @param entity
+ * The entitiy to attach
+ * */
protected void attachEntity(T entity) {
}
/**
* Updates the given entities in the database using a transaction.
*
- * @param entities The entities to insert.
+ * @param entities
+ * The entities to insert.
*/
public void updateInTx(Iterable entities) {
SQLiteStatement stmt = statements.getUpdateStatement();
@@ -783,7 +754,8 @@ public void updateInTx(Iterable entities) {
/**
* Updates the given entities in the database using a transaction.
*
- * @param entities The entities to update.
+ * @param entities
+ * The entities to update.
*/
public void updateInTx(T... entities) {
updateInTx(Arrays.asList(entities));
diff --git a/DaoCore/src/main/java/de/greenrobot/dao/Property.java b/DaoCore/src/main/java/de/greenrobot/dao/Property.java
index 77923eb71..eddd6e405 100644
--- a/DaoCore/src/main/java/de/greenrobot/dao/Property.java
+++ b/DaoCore/src/main/java/de/greenrobot/dao/Property.java
@@ -33,13 +33,17 @@ public class Property {
public final String name;
public final boolean primaryKey;
public final String columnName;
+ public final String sqlType;
+ public final int version;
- public Property(int ordinal, Class> type, String name, boolean primaryKey, String columnName) {
+ public Property(int ordinal, Class> type, String name, boolean primaryKey, String columnName, String sqlType, int version) {
this.ordinal = ordinal;
this.type = type;
this.name = name;
this.primaryKey = primaryKey;
this.columnName = columnName;
+ this.sqlType = sqlType;
+ this.version = version;
}
/** Creates an "equal ('=')" condition for this property. */
diff --git a/DaoCore/src/main/java/de/greenrobot/dao/internal/SqlUtils.java b/DaoCore/src/main/java/de/greenrobot/dao/internal/SqlUtils.java
index 3e328bc95..b9cdf407e 100644
--- a/DaoCore/src/main/java/de/greenrobot/dao/internal/SqlUtils.java
+++ b/DaoCore/src/main/java/de/greenrobot/dao/internal/SqlUtils.java
@@ -104,12 +104,12 @@ public static String createSqlInsert(String insertInto, String tablename, String
}
/** Creates an select for given columns with a trailing space */
- public static String createSqlSelect(String tablename, String tableAlias, String[] columns, boolean distinct) {
+ public static String createSqlSelect(String tablename, String tableAlias, String[] columns) {
if (tableAlias == null || tableAlias.length() < 0) {
throw new DaoException("Table alias required");
}
- StringBuilder builder = new StringBuilder(distinct ? "SELECT DISTINCT " : "SELECT ");
+ StringBuilder builder = new StringBuilder("SELECT ");
SqlUtils.appendColumns(builder, tableAlias, columns).append(" FROM ");
builder.append('"').append(tablename).append('"').append(' ').append(tableAlias).append(' ');
return builder.toString();
diff --git a/DaoCore/src/main/java/de/greenrobot/dao/internal/TableStatements.java b/DaoCore/src/main/java/de/greenrobot/dao/internal/TableStatements.java
index 864b6e04e..9414f1f71 100644
--- a/DaoCore/src/main/java/de/greenrobot/dao/internal/TableStatements.java
+++ b/DaoCore/src/main/java/de/greenrobot/dao/internal/TableStatements.java
@@ -77,7 +77,7 @@ public SQLiteStatement getUpdateStatement() {
/** ends with an space to simplify appending to this string. */
public String getSelectAll() {
if (selectAll == null) {
- selectAll = SqlUtils.createSqlSelect(tablename, "T", allColumns, false);
+ selectAll = SqlUtils.createSqlSelect(tablename, "T", allColumns);
}
return selectAll;
}
@@ -85,7 +85,7 @@ public String getSelectAll() {
/** ends with an space to simplify appending to this string. */
public String getSelectKeys() {
if (selectKeys == null) {
- selectKeys = SqlUtils.createSqlSelect(tablename, "T", pkColumns, false);
+ selectKeys = SqlUtils.createSqlSelect(tablename, "T", pkColumns);
}
return selectKeys;
}
diff --git a/DaoCore/src/main/java/de/greenrobot/dao/query/Join.java b/DaoCore/src/main/java/de/greenrobot/dao/query/Join.java
index 04dba3fe2..ab142a068 100644
--- a/DaoCore/src/main/java/de/greenrobot/dao/query/Join.java
+++ b/DaoCore/src/main/java/de/greenrobot/dao/query/Join.java
@@ -80,12 +80,4 @@ public WhereCondition and(WhereCondition cond1, WhereCondition cond2, WhereCondi
return whereCollector.combineWhereConditions(" AND ", cond1, cond2, condMore);
}
- /**
- * Usually you don't need this value; just in case you are mixing custom
- * {@link de.greenrobot.dao.query.WhereCondition.StringCondition} into the query, this value allows to reference
- * the joined (target) table.
- */
- public String getTablePrefix() {
- return tablePrefix;
- }
}
diff --git a/DaoCore/src/main/java/de/greenrobot/dao/query/QueryBuilder.java b/DaoCore/src/main/java/de/greenrobot/dao/query/QueryBuilder.java
index 2e6218381..e6c15ec67 100644
--- a/DaoCore/src/main/java/de/greenrobot/dao/query/QueryBuilder.java
+++ b/DaoCore/src/main/java/de/greenrobot/dao/query/QueryBuilder.java
@@ -58,7 +58,6 @@ public class QueryBuilder {
private Integer limit;
private Integer offset;
- private boolean distinct;
/** For internal use by greenDAO only. */
public static QueryBuilder internalCreate(AbstractDao dao) {
@@ -85,12 +84,6 @@ private void checkOrderBuilder() {
}
}
- /** Use a SELECT DISTINCT to avoid duplicate entities returned, e.g. when doing joins. */
- public QueryBuilder distinct() {
- distinct = true;
- return this;
- }
-
/**
* Adds the given conditions to the where clause using an logical AND. To create new conditions, use the properties
* given in the generated dao classes.
@@ -269,7 +262,7 @@ public CursorQuery buildCursor() {
}
private StringBuilder createSelectBuilder() {
- String select = SqlUtils.createSqlSelect(dao.getTablename(), tablePrefix, dao.getAllColumns(), distinct);
+ String select = SqlUtils.createSqlSelect(dao.getTablename(), tablePrefix, dao.getAllColumns());
StringBuilder builder = new StringBuilder(select);
appendJoinsAndWheres(builder, tablePrefix);
@@ -280,6 +273,7 @@ private StringBuilder createSelectBuilder() {
return builder;
}
+
private int checkAddLimit(StringBuilder builder) {
int limitPosition = -1;
if (limit != null) {
diff --git a/DaoGenerator/build.gradle b/DaoGenerator/build.gradle
index 843f81412..ccdbde8b1 100644
--- a/DaoGenerator/build.gradle
+++ b/DaoGenerator/build.gradle
@@ -4,8 +4,8 @@ apply plugin: 'signing'
group = 'de.greenrobot'
archivesBaseName = 'greendao-generator'
-version = '2.1.1-SNAPSHOT'
-sourceCompatibility = 1.7
+version = '2.0.0'
+sourceCompatibility = 1.6
def isSnapshot = version.endsWith('-SNAPSHOT')
def sonatypeRepositoryUrl
@@ -27,7 +27,7 @@ configurations {
}
dependencies {
- compile 'org.freemarker:freemarker:2.3.23'
+ compile 'org.freemarker:freemarker:2.3.22'
testCompile 'junit:junit:4.12'
// deployerJars 'org.apache.maven.wagon:wagon-webdav-jackrabbit:2.4'
deployerJars 'org.apache.maven.wagon:wagon-webdav:1.0-beta-2'
diff --git a/DaoGenerator/src-template/dao-master.ftl b/DaoGenerator/src-template/dao-master.ftl
index adaffc487..6f6bd55e3 100644
--- a/DaoGenerator/src-template/dao-master.ftl
+++ b/DaoGenerator/src-template/dao-master.ftl
@@ -81,6 +81,56 @@ public class DaoMaster extends AbstractDaoMaster {
dropAllTables(db, true);
onCreate(db);
}
+
+ }
+
+ /** WARNING: Drops all table on Upgrade! Use only during development. */
+ public static class AutoUpdateOpenHelper extends OpenHelper {
+ public AutoUpdateOpenHelper(Context context, String name, CursorFactory factory) {
+ super(context, name, factory);
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ db.beginTransaction();
+ try {
+<#list schema.entities as entity>
+ ${entity.classNameDao}.updateTable(db, oldVersion, newVersion);
+#list>
+ db.setTransactionSuccessful();
+ } finally {
+ db.endTransaction();
+ }
+
+ }
+
+ }
+
+ /** WARNING: Drops all table on Upgrade! Use only during development. */
+ public static class DevAutoUpdateOpenHelper extends OpenHelper {
+ public DevAutoUpdateOpenHelper(Context context, String name, CursorFactory factory) {
+ super(context, name, factory);
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ db.beginTransaction();
+ try {
+<#list schema.entities as entity>
+ ${entity.classNameDao}.updateTable(db, oldVersion, newVersion);
+#list>
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ Log.i("greenDAO", "Upgrading schema from version " + oldVersion + " to " + newVersion + " by dropping all tables");
+ dropAllTables(db, true);
+ onCreate(db);
+ } finally {
+ db.endTransaction();
+ }
+
+ }
+
}
public DaoMaster(SQLiteDatabase db) {
diff --git a/DaoGenerator/src-template/dao.ftl b/DaoGenerator/src-template/dao.ftl
index 60f7045b1..bdf9a272a 100644
--- a/DaoGenerator/src-template/dao.ftl
+++ b/DaoGenerator/src-template/dao.ftl
@@ -30,6 +30,7 @@ import java.util.ArrayList;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteStatement;
+import android.util.Log;
import de.greenrobot.dao.AbstractDao;
import de.greenrobot.dao.Property;
@@ -64,6 +65,8 @@ import ${entity.javaPackage}.${entity.className}.Builder;
public class ${entity.classNameDao} extends AbstractDao<${entity.className}, ${entity.pkType}> {
public static final String TABLENAME = "${entity.tableName}";
+
+ public static final String TAG = "${entity.classNameDao}";
/**
* Properties of entity ${entity.className}.
@@ -71,8 +74,15 @@ public class ${entity.classNameDao} extends AbstractDao<${entity.className}, ${e
*/
public static class Properties {
<#list entity.propertiesColumns as property>
- public final static Property ${property.propertyName?cap_first} = new Property(${property_index}, ${property.javaType}.class, "${property.propertyName}", ${property.primaryKey?string}, "${property.columnName}");
+ public final static Property ${property.propertyName?cap_first} = new Property(${property_index}, ${property.javaType}.class, "${property.propertyName}", ${property.primaryKey?string}, "${property.columnName}", "${property.columnType}", ${property.version});
#list>
+
+ public final static Property [] all = {
+<#list entity.propertiesColumns as property>
+ ${property.propertyName?cap_first},
+#list>
+ };
+
};
<#if entity.active>
@@ -114,6 +124,31 @@ as property>\"${property.columnName}\"<#if property_has_next>,#if>#list>);")
#list>
#if>
}
+
+ public static void updateTable(SQLiteDatabase db, int oldVer, int newVer) {
+ for (Property p : Properties.all) {
+ if (p.version > oldVer) {
+ Cursor cursor = db.rawQuery("PRAGMA table_info("+ TABLENAME +")", null);
+ if (cursor != null) {
+ boolean skip = false;
+ while (cursor.moveToNext()) {
+ String name = cursor.getString(cursor.getColumnIndex("name"));
+ if (p.columnName.equalsIgnoreCase(name)) {
+ skip = true;
+ break;
+ }
+ }
+ if (skip) {
+ Log.w(TAG, "Skipping add column '" + p.columnName + "' because already exists");
+ continue;
+ }
+ cursor.close();
+ }
+ Log.i(TAG, "Alter table " + TABLENAME + " add column '" + p.columnName + "' " + p.sqlType);
+ db.execSQL("ALTER TABLE \"" + TABLENAME + "\" ADD \"" + p.columnName + "\" " + p.sqlType);
+ }
+ }
+ }
/** Drops the underlying database table. */
public static void dropTable(SQLiteDatabase db, boolean ifExists) {
diff --git a/DaoGenerator/src-template/entity.ftl b/DaoGenerator/src-template/entity.ftl
index 0e383d847..5fd44b8b0 100644
--- a/DaoGenerator/src-template/entity.ftl
+++ b/DaoGenerator/src-template/entity.ftl
@@ -44,17 +44,9 @@ import ${additionalImport};
<#else>
// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT. Enable "keep" sections if you want to edit.
#if>
-<#if entity.javaDoc ??>
-
-${entity.javaDoc}
-<#else>
/**
* Entity mapped to table "${entity.tableName}".
*/
-#if>
-<#if entity.codeBeforeClass ??>
-${entity.codeBeforeClass}
-#if>
public class ${entity.className}<#if
entity.superclass?has_content> extends ${entity.superclass} #if><#if
entity.interfacesToImplement?has_content> implements <#list entity.interfacesToImplement
@@ -64,9 +56,6 @@ as ifc>${ifc}<#if ifc_has_next>, #if>#list>#if> {
<#if property.notNull && complexTypes?seq_contains(property.propertyType)>
/** Not-null value. */
#if>
-<#if property.javaDocField ??>
-${property.javaDocField}
-#if>
<#if property.codeBeforeField ??>
${property.codeBeforeField}
#if>
@@ -112,6 +101,36 @@ property>${property.javaType} ${property.propertyName}<#if property_has_next>, <
}
#if>
+<#if entity.parcelable>
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+<#list entity.properties as property>
+ ${property.parcelableWriteStatement}
+#list>
+ }
+
+ private ${entity.className}(Parcel in) {
+<#list entity.properties as property>
+ ${property.parcelableReadStatement}
+#list>
+ }
+
+ public static final Parcelable.Creator<${entity.className}> CREATOR = new Parcelable.Creator<${entity.className}>() {
+ public ${entity.className} createFromParcel(Parcel in) {
+ return new ${entity.className}(in);
+ }
+
+ public ${entity.className} [] newArray(int size) {
+ return new ${entity.className}[size];
+ }
+ };
+#if>
+
public ${entity.className}(<#list entity.properties as
property>${property.javaTypeInEntity} ${property.propertyName}<#if property_has_next>, #if>#list>) {
<#list entity.properties as property>
@@ -132,9 +151,6 @@ property>${property.javaTypeInEntity} ${property.propertyName}<#if property_has_
<#if property.notNull && complexTypes?seq_contains(property.propertyType)>
/** Not-null value. */
#if>
-<#if property.javaDocGetter ??>
-${property.javaDocGetter}
-#if>
<#if property.codeBeforeGetter ??>
${property.codeBeforeGetter}
#if>
@@ -145,9 +161,6 @@ ${property.javaDocGetter}
<#if property.notNull && complexTypes?seq_contains(property.propertyType)>
/** Not-null value; ensure this value is available before it is saved to the database. */
#if>
-<#if property.javaDocSetter ??>
-${property.javaDocSetter}
-#if>
<#if property.codeBeforeSetter ??>
${property.codeBeforeSetter}
#if>
diff --git a/DaoGenerator/src/de/greenrobot/daogenerator/DaoGenerator.java b/DaoGenerator/src/de/greenrobot/daogenerator/DaoGenerator.java
index bb25fe9a1..0828ca40c 100644
--- a/DaoGenerator/src/de/greenrobot/daogenerator/DaoGenerator.java
+++ b/DaoGenerator/src/de/greenrobot/daogenerator/DaoGenerator.java
@@ -28,6 +28,7 @@
import java.util.regex.Pattern;
import freemarker.template.Configuration;
+import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
/**
@@ -57,8 +58,9 @@ public DaoGenerator() throws IOException {
patternKeepFields = compilePattern("FIELDS");
patternKeepMethods = compilePattern("METHODS");
- Configuration config = new Configuration(Configuration.VERSION_2_3_23);
+ Configuration config = new Configuration();
config.setClassForTemplateLoading(this.getClass(), "/");
+ config.setObjectWrapper(new DefaultObjectWrapper());
templateDao = config.getTemplate("dao.ftl");
templateDaoMaster = config.getTemplate("dao-master.ftl");
diff --git a/DaoGenerator/src/de/greenrobot/daogenerator/DaoUtil.java b/DaoGenerator/src/de/greenrobot/daogenerator/DaoUtil.java
index a8a2e9658..feb76469c 100644
--- a/DaoGenerator/src/de/greenrobot/daogenerator/DaoUtil.java
+++ b/DaoGenerator/src/de/greenrobot/daogenerator/DaoUtil.java
@@ -104,11 +104,5 @@ public static int copyAllBytes(InputStream in, OutputStream out) throws IOExcept
return byteCount;
}
- public static String checkConvertToJavaDoc(String javaDoc, String indent) {
- if (javaDoc != null && !javaDoc.trim().startsWith("/**")) {
- javaDoc = javaDoc.replace("\n", "\n" + indent + " * ");
- javaDoc = indent + "/**\n" + indent + " * " + javaDoc + "\n" + indent + " */";
- }
- return javaDoc;
- }
+
}
diff --git a/DaoGenerator/src/de/greenrobot/daogenerator/Entity.java b/DaoGenerator/src/de/greenrobot/daogenerator/Entity.java
index da865a423..2d46158e3 100644
--- a/DaoGenerator/src/de/greenrobot/daogenerator/Entity.java
+++ b/DaoGenerator/src/de/greenrobot/daogenerator/Entity.java
@@ -17,6 +17,8 @@
*/
package de.greenrobot.daogenerator;
+import de.greenrobot.daogenerator.Property.PropertyBuilder;
+
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
@@ -24,8 +26,6 @@
import java.util.Set;
import java.util.TreeSet;
-import de.greenrobot.daogenerator.Property.PropertyBuilder;
-
/**
* Model class for an entity: a Java data object mapped to a data base table. A new entity is added to a {@link Schema}
* by the method {@link Schema#addEntity(String)} (there is no public constructor for {@link Entity} itself).
@@ -64,8 +64,6 @@ public class Entity {
private Property pkProperty;
private String pkType;
private String superclass;
- private String javaDoc;
- private String codeBeforeClass;
private boolean protobuf;
private boolean constructors;
@@ -74,6 +72,7 @@ public class Entity {
private boolean skipTableCreation;
private Boolean active;
private Boolean hasKeepSections;
+ private boolean parcelable = false;
Entity(Schema schema, String className) {
this.schema = schema;
@@ -444,41 +443,41 @@ public List getContentProviders() {
return contentProviders;
}
- public void implementsInterface(String... interfaces) {
+ public Entity implementsInterface(String... interfaces) {
for (String interfaceToImplement : interfaces) {
if (interfacesToImplement.contains(interfaceToImplement)) {
throw new RuntimeException("Interface defined more than once: " + interfaceToImplement);
}
interfacesToImplement.add(interfaceToImplement);
}
+ return this;
}
public void implementsSerializable() {
interfacesToImplement.add("java.io.Serializable");
}
+
+ /**
+ * Generates all the Android Parcelable methods. Only Fields marked as notNull() will be parceled.
+ * @return
+ */
+ public Entity implementsParcelable() {
+ interfacesToImplement.add("Parcelable");
+ parcelable = true;
+ return addImport("android.os.*");
+ }
+
+ public boolean isParcelable() {
+ return parcelable;
+ }
public String getSuperclass() {
return superclass;
}
- public void setSuperclass(String classToExtend) {
+ public Entity setSuperclass(String classToExtend) {
this.superclass = classToExtend;
- }
-
- public String getJavaDoc() {
- return javaDoc;
- }
-
- public void setJavaDoc(String javaDoc) {
- this.javaDoc = DaoUtil.checkConvertToJavaDoc(javaDoc, "");
- }
-
- public String getCodeBeforeClass() {
- return codeBeforeClass;
- }
-
- public void setCodeBeforeClass(String codeBeforeClass) {
- this.codeBeforeClass = codeBeforeClass;
+ return this;
}
void init2ndPass() {
@@ -596,6 +595,12 @@ void init3rdPass() {
init3rdPassRelations();
init3rdPassAdditionalImports();
}
+
+ void initParcelablePass() {
+ for (Property property: properties) {
+ property.initParcelableMethods();
+ }
+ }
private void init3rdPassRelations() {
Set toOneNames = new HashSet();
diff --git a/DaoGenerator/src/de/greenrobot/daogenerator/Property.java b/DaoGenerator/src/de/greenrobot/daogenerator/Property.java
index 14534df55..a7bdc48a8 100644
--- a/DaoGenerator/src/de/greenrobot/daogenerator/Property.java
+++ b/DaoGenerator/src/de/greenrobot/daogenerator/Property.java
@@ -131,35 +131,13 @@ public PropertyBuilder codeBeforeGetterAndSetter(String code) {
return this;
}
- public PropertyBuilder javaDocField(String javaDoc) {
- property.javaDocField = checkConvertToJavaDoc(javaDoc);
- return this;
- }
-
- private String checkConvertToJavaDoc(String javaDoc) {
- return DaoUtil.checkConvertToJavaDoc(javaDoc, " ");
- }
-
- public PropertyBuilder javaDocGetter(String javaDoc) {
- property.javaDocGetter = checkConvertToJavaDoc(javaDoc);
- return this;
- }
-
- public PropertyBuilder javaDocSetter(String javaDoc) {
- property.javaDocSetter = checkConvertToJavaDoc(javaDoc);
- return this;
- }
-
- public PropertyBuilder javaDocGetterAndSetter(String javaDoc) {
- javaDoc = checkConvertToJavaDoc(javaDoc);
- property.javaDocGetter = javaDoc;
- property.javaDocSetter = javaDoc;
- return this;
- }
-
public Property getProperty() {
return property;
}
+
+ public void setVersion(int rawVersionDontForgetToBump) {
+ property.version = rawVersionDontForgetToBump;
+ }
}
private final Schema schema;
@@ -179,10 +157,6 @@ public Property getProperty() {
private String codeBeforeGetter;
private String codeBeforeSetter;
- private String javaDocField;
- private String javaDocGetter;
- private String javaDocSetter;
-
private boolean primaryKey;
private boolean pkAsc;
private boolean pkDesc;
@@ -197,6 +171,10 @@ public Property getProperty() {
private int ordinal;
private String javaType;
+ private String parcelableWriteStatement = "";
+ private String parcelableReadStatement = "";
+
+ private int version = -1;
public Property(Schema schema, Entity entity, PropertyType propertyType, String propertyName) {
this.schema = schema;
@@ -249,7 +227,15 @@ public String getJavaType() {
return javaType;
}
- public String getJavaTypeInEntity() {
+ public final String getParcelableWriteStatement() {
+ return parcelableWriteStatement;
+ }
+
+ public final String getParcelableReadStatement() {
+ return parcelableReadStatement;
+ }
+
+ public String getJavaTypeInEntity() {
if (customTypeClassName != null) {
return customTypeClassName;
} else {
@@ -293,18 +279,6 @@ public String getCodeBeforeSetter() {
return codeBeforeSetter;
}
- public String getJavaDocField() {
- return javaDocField;
- }
-
- public String getJavaDocGetter() {
- return javaDocGetter;
- }
-
- public String getJavaDocSetter() {
- return javaDocSetter;
- }
-
public String getDatabaseValueExpression() {
return getDatabaseValueExpression(propertyName);
}
@@ -312,6 +286,14 @@ public String getDatabaseValueExpression() {
public String getDatabaseValueExpressionNotNull() {
return getDatabaseValueExpression("entity.get" + DaoUtil.capFirst(propertyName) + "()");
}
+
+ /**
+ * version this field was added. can be used in the onUpgrade callback to auto update.
+ * @return
+ */
+ public String getVersion() {
+ return String.valueOf(version);
+ }
// Got too messy in template:
// <#if property.customType?has_content>${property.propertyName}Converter.convertToDatabaseValue(#if><#--
@@ -326,9 +308,9 @@ public String getDatabaseValueExpression(String entityValue) {
if (customType != null) {
builder.append(')');
}
- if (propertyType == PropertyType.Boolean) {
+ if(propertyType == PropertyType.Boolean) {
builder.append(" ? 1L: 0L");
- } else if (propertyType == PropertyType.Date) {
+ } else if(propertyType == PropertyType.Date) {
builder.append(".getTime()");
}
return builder.toString();
@@ -345,15 +327,16 @@ public String getEntityValueExpression(String databaseValue) {
if (customType != null) {
builder.append(propertyName).append("Converter.convertToEntityProperty(");
}
- if (propertyType == PropertyType.Byte) {
+ if(propertyType == PropertyType.Byte) {
builder.append("(byte) ");
- } else if (propertyType == PropertyType.Date) {
+ }else
+ if(propertyType == PropertyType.Date) {
builder.append("new java.util.Date(");
}
builder.append(databaseValue);
- if (propertyType == PropertyType.Boolean) {
+ if(propertyType == PropertyType.Boolean) {
builder.append(" != 0");
- } else if (propertyType == PropertyType.Date) {
+ } else if(propertyType == PropertyType.Date) {
builder.append(")");
}
if (customType != null) {
@@ -412,6 +395,81 @@ private void initConstraint() {
void init3ndPass() {
// Nothing to do so far
}
+
+ void initParcelableMethods() {
+ switch (propertyType) {
+ case Boolean:
+ parcelableReadStatement = propertyName + " = in.readByte() != 0;";
+ if (notNull) {
+ parcelableWriteStatement = "out.writeByte((byte)(" + propertyName + " ? 1 : 0));";
+ } else {
+ parcelableWriteStatement = "if (" + propertyName + " == null) out.writeByte((byte)0); else out.writeByte((byte)(" + propertyName + " ? 1 : 0));";
+ }
+ break;
+ case Byte:
+ parcelableReadStatement = propertyName + " = in.readByte();";
+ if (notNull) {
+ parcelableWriteStatement = "out.writeByte(" + propertyName + ");";
+ } else {
+ parcelableWriteStatement = "if (" + propertyName + " == null) out.writeByte((byte)0); else out.writeByte(" + propertyName + ");";
+ }
+ break;
+ case ByteArray:
+ if (notNull) {
+ parcelableReadStatement = propertyName + "in.readByteArray(" + propertyName + ");";
+ parcelableWriteStatement = "out.writeByteArray(" + propertyName + ");";
+ }
+ break;
+ case Date:
+ parcelableReadStatement = propertyName + " = new java.util.Date(in.readLong());";
+ parcelableWriteStatement = "out.writeLong(" + propertyName + " == null ? 0 : " + propertyName + ".getTime());";
+ break;
+ case Double:
+ parcelableReadStatement = propertyName + " = in.readDouble();";
+ if (notNull) {
+ parcelableWriteStatement = "out.writeDouble(" + propertyName + ");";
+ } else {
+ parcelableWriteStatement = "if (" + propertyName + " == null) out.writeDouble(0); else out.writeDouble(" + propertyName + ");";
+ }
+ break;
+ case Float:
+ parcelableReadStatement = propertyName + " = in.readFloat();";
+ if (notNull) {
+ parcelableWriteStatement = "out.writeFloat(" + propertyName + ");";
+ } else {
+ parcelableWriteStatement = "if (" + propertyName + " == null) out.writeFloat(0); else out.writeFloat(" + propertyName + ");";
+ }
+ break;
+ case Int:
+ parcelableReadStatement = propertyName + " = in.readInt();";
+ if (notNull) {
+ parcelableWriteStatement = "out.writeInt(" + propertyName + ");";
+ } else {
+ parcelableWriteStatement = "if (" + propertyName + " == null) out.writeInt(0); else out.writeInt(" + propertyName + ");";
+ }
+ break;
+ case Long:
+ parcelableReadStatement = propertyName + " = in.readLong();";
+ if (notNull) {
+ parcelableWriteStatement = "out.writeLong(" + propertyName + ");";
+ } else {
+ parcelableWriteStatement = "if (" + propertyName + " == null) out.writeLong(0); else out.writeLong(" + propertyName + ");";
+ }
+ break;
+ case Short:
+ parcelableReadStatement = propertyName + " = in.readInt();";
+ if (notNull) {
+ parcelableWriteStatement = "out.writeInt(" + propertyName + ");";
+ } else {
+ parcelableWriteStatement = "if (" + propertyName + " == null) out.writeInt(0); else out.writeInt(" + propertyName + ");";
+ }
+ break;
+ case String:
+ parcelableReadStatement = propertyName + " = in.readString();";
+ parcelableWriteStatement = "out.writeString(" + propertyName + ");";
+ break;
+ }
+ }
@Override
public String toString() {
diff --git a/DaoGenerator/src/de/greenrobot/daogenerator/Schema.java b/DaoGenerator/src/de/greenrobot/daogenerator/Schema.java
index 8351ecb55..236a17687 100644
--- a/DaoGenerator/src/de/greenrobot/daogenerator/Schema.java
+++ b/DaoGenerator/src/de/greenrobot/daogenerator/Schema.java
@@ -183,6 +183,9 @@ void init2ndPass() {
void init3rdPass() {
for (Entity entity : entities) {
entity.init3rdPass();
+ if (entity.isParcelable()) {
+ entity.initParcelablePass();
+ }
}
}
diff --git a/DaoGenerator/src/de/greenrobot/daogenerator/ToManyWithJoinEntity.java b/DaoGenerator/src/de/greenrobot/daogenerator/ToManyWithJoinEntity.java
index 0f897f054..752215669 100644
--- a/DaoGenerator/src/de/greenrobot/daogenerator/ToManyWithJoinEntity.java
+++ b/DaoGenerator/src/de/greenrobot/daogenerator/ToManyWithJoinEntity.java
@@ -45,8 +45,8 @@ public Property getTargetProperty() {
return targetProperty;
}
- void init3rdPass() {
- super.init3rdPass();
+ void init2ndPass() {
+ super.init2ndPass();
List pks = sourceEntity.getPropertiesPk();
if (pks.isEmpty()) {
throw new RuntimeException("Source entity has no primary key, but we need it for " + this);
@@ -57,4 +57,8 @@ void init3rdPass() {
}
}
+ void init3rdPass() {
+ super.init3rdPass();
+ }
+
}
diff --git a/DaoTest/build.gradle b/DaoTest/build.gradle
index 0947debdd..74707af29 100644
--- a/DaoTest/build.gradle
+++ b/DaoTest/build.gradle
@@ -12,6 +12,7 @@ apply plugin: 'com.android.application'
dependencies {
androidTestCompile project(':DaoCore')
+ androidTestCompile project(':PerformanceTests:Common')
testCompile project(':DaoCore')
testCompile 'org.robolectric:robolectric:3.0'
diff --git a/DaoTest/src-gen/de/greenrobot/daotest/TestEntity.java b/DaoTest/src-gen/de/greenrobot/daotest/TestEntity.java
index 15863049b..748cee08a 100644
--- a/DaoTest/src-gen/de/greenrobot/daotest/TestEntity.java
+++ b/DaoTest/src-gen/de/greenrobot/daotest/TestEntity.java
@@ -1,17 +1,11 @@
package de.greenrobot.daotest;
// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT. Enable "keep" sections if you want to edit.
-
/**
- * This entity is used by internal tests of greenDAO.
- * (This JavaDoc is defined in the generator project.)
+ * Entity mapped to table "TEST_ENTITY".
*/
-// This is another test comment, you could also apply annotations like this
public class TestEntity {
- /**
- * JavaDoc test field
- */
private Long id;
private int simpleInt;
private Integer simpleInteger;
@@ -52,9 +46,6 @@ public void setId(Long id) {
this.id = id;
}
- /**
- * JavaDoc test getter
- */
public int getSimpleInt() {
return simpleInt;
}
@@ -67,25 +58,16 @@ public Integer getSimpleInteger() {
return simpleInteger;
}
- /**
- * JavaDoc test setter
- */
public void setSimpleInteger(Integer simpleInteger) {
this.simpleInteger = simpleInteger;
}
/** Not-null value. */
- /**
- * JavaDoc test getter and setter
- */
public String getSimpleStringNotNull() {
return simpleStringNotNull;
}
/** Not-null value; ensure this value is available before it is saved to the database. */
- /**
- * JavaDoc test getter and setter
- */
public void setSimpleStringNotNull(String simpleStringNotNull) {
this.simpleStringNotNull = simpleStringNotNull;
}
diff --git a/DaoTest/src/de/greenrobot/daotest/performance/IndexedStringPerformanceTest.java b/DaoTest/src/de/greenrobot/daotest/performance/IndexedStringPerformanceTest.java
index dfb30b633..1a0822ec3 100644
--- a/DaoTest/src/de/greenrobot/daotest/performance/IndexedStringPerformanceTest.java
+++ b/DaoTest/src/de/greenrobot/daotest/performance/IndexedStringPerformanceTest.java
@@ -4,7 +4,7 @@
import de.greenrobot.dao.test.AbstractDaoTest;
import de.greenrobot.daotest.IndexedStringEntity;
import de.greenrobot.daotest.IndexedStringEntityDao;
-
+import de.greenrobot.performance.StringGenerator;
import java.util.ArrayList;
import java.util.List;
diff --git a/DaoTest/src/de/greenrobot/daotest/query/QueryBuilderSimpleTest.java b/DaoTest/src/de/greenrobot/daotest/query/QueryBuilderSimpleTest.java
index 221a80bde..a8dbcc4bc 100644
--- a/DaoTest/src/de/greenrobot/daotest/query/QueryBuilderSimpleTest.java
+++ b/DaoTest/src/de/greenrobot/daotest/query/QueryBuilderSimpleTest.java
@@ -250,14 +250,4 @@ public void testLike() {
assertNull(entity2);
}
- public void testDistinct() {
- TestEntity entity = insert(3).get(1);
-
- Query query = dao.queryBuilder().distinct()
- .where(Properties.SimpleString.eq(entity.getSimpleString())).build();
- TestEntity entity2 = query.uniqueOrThrow();
- assertEquals(entity.getId(), entity2.getId());
- // TODO improve test to check functionality
- }
-
}
diff --git a/DaoTestGenerator/src/de/greenrobot/daogenerator/gentest/TestDaoGenerator.java b/DaoTestGenerator/src/de/greenrobot/daogenerator/gentest/TestDaoGenerator.java
index f42d1d36e..88ba60800 100644
--- a/DaoTestGenerator/src/de/greenrobot/daogenerator/gentest/TestDaoGenerator.java
+++ b/DaoTestGenerator/src/de/greenrobot/daogenerator/gentest/TestDaoGenerator.java
@@ -105,13 +105,10 @@ protected void createSimpleNotNull() {
protected Entity createTest() {
Entity testEntity = schema.addEntity("TestEntity");
- testEntity.setJavaDoc("This entity is used by internal tests of greenDAO.\n" +
- "(This JavaDoc is defined in the generator project.)");
- testEntity.setCodeBeforeClass("// This is another test comment, you could also apply annotations like this");
- testEntity.addIdProperty().javaDocField("JavaDoc test field");
- testEntity.addIntProperty("simpleInt").notNull().javaDocGetter("JavaDoc test getter");
- testEntity.addIntProperty("simpleInteger").javaDocSetter("JavaDoc test setter");
- testEntity.addStringProperty("simpleStringNotNull").notNull().javaDocGetterAndSetter("JavaDoc test getter and setter");
+ testEntity.addIdProperty();
+ testEntity.addIntProperty("simpleInt").notNull();
+ testEntity.addIntProperty("simpleInteger");
+ testEntity.addStringProperty("simpleStringNotNull").notNull();
testEntity.addStringProperty("simpleString");
testEntity.addStringProperty("indexedString").index();
testEntity.addStringProperty("indexedStringAscUnique").indexAsc(null, true);
diff --git a/README.md b/README.md
index 5df7e6941..2560bd888 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,8 @@
-**Please help us with this short survey: http://bit.ly/greendao-survey Thanks for your support!**
-
greenDAO
========
greenDAO is a light & fast ORM solution for Android that maps objects to SQLite databases. Being highly optimized for Android, greenDAO offers great performance and consumes minimal memory.
-**Home page, documentation, and support links: http://greenrobot.org/greendao/**
+**Home page, documentation, and support links: http://greendao-orm.com/**
[![Build Status](https://travis-ci.org/greenrobot/greenDAO.svg?branch=master)](https://travis-ci.org/greenrobot/greenDAO)
diff --git a/settings.gradle b/settings.gradle
index ef5f41d27..660b6cd5b 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -2,4 +2,12 @@ include 'DaoCore', 'DaoGenerator', 'DaoExampleGenerator'
include 'DaoTest' // Travis needs some Android setup for this
include 'DaoTestGenerator'
include ':DaoExample'
-
+include ':PerformanceTests:Common'
+include ':PerformanceTests:ActiveAndroid'
+include ':PerformanceTests:Couchbase'
+include ':PerformanceTests:Cupboard'
+include ':PerformanceTests:Firebase'
+include ':PerformanceTests:OrmLite'
+include ':PerformanceTests:Parse'
+include ':PerformanceTests:Realm'
+include ':PerformanceTests:Sqlite'