From 1d510fa4687f6a3a22e3bc620279057b3ee3e274 Mon Sep 17 00:00:00 2001 From: passos Date: Tue, 11 Aug 2020 06:02:46 -0700 Subject: [PATCH] fix the generation issues when primary key is a custom type When primary key is a custom type, the generated code for updateKeyAfterInsert and getKey will return String but the actual primary key is not. see https://github.com/greenrobot/greenDAO/issues/1051 for details --- DaoGenerator/src-template/dao.ftl | 3 +- DaoGenerator/src-template/entity.ftl | 2 +- .../greenrobot/greendao/generator/Entity.java | 4 +- .../entity/CustomPkTypeEntityTest.java | 65 +++++++++ .../greendao/daotest/CustomPkTypeEntity.java | 50 +++++++ .../daotest/CustomPkTypeEntityDao.java | 130 ++++++++++++++++++ .../greendao/daotest/DaoMaster.java | 3 + .../greendao/daotest/DaoSession.java | 14 ++ .../daotest/customtype/UuidConverter.java | 17 +++ .../generator/gentest/TestDaoGenerator.java | 7 + 10 files changed, 292 insertions(+), 3 deletions(-) create mode 100644 tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/entity/CustomPkTypeEntityTest.java create mode 100644 tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/CustomPkTypeEntity.java create mode 100644 tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/CustomPkTypeEntityDao.java create mode 100644 tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/customtype/UuidConverter.java diff --git a/DaoGenerator/src-template/dao.ftl b/DaoGenerator/src-template/dao.ftl index 08eb4eee4..b575cf3c3 100644 --- a/DaoGenerator/src-template/dao.ftl +++ b/DaoGenerator/src-template/dao.ftl @@ -181,7 +181,8 @@ as property>\"${property.dbName}\"<#if (index.propertiesOrder[property_index])?? <#if entity.pkProperty??> return <#if !entity.pkProperty.notNull>cursor.isNull(offset + ${entity.pkProperty.ordinal}) ? null : <#if entity.pkProperty.propertyType == "Byte">(byte) <#if - entity.pkProperty.propertyType == "Date">new java.util.Date(cursor.get${toCursorType[entity.pkProperty.propertyType]}(offset + ${entity.pkProperty.ordinal})<#if + entity.pkProperty.propertyType == "Date">new java.util.Date(<#-- + -->${entity.pkProperty.getEntityValueExpression("cursor.get${toCursorType[entity.pkProperty.propertyType]}(offset + ${entity.pkProperty.ordinal})")}<#if entity.pkProperty.propertyType == "Boolean"> != 0<#if entity.pkProperty.propertyType == "Date">); <#else> diff --git a/DaoGenerator/src-template/entity.ftl b/DaoGenerator/src-template/entity.ftl index f23cfc8f4..b93145bbe 100644 --- a/DaoGenerator/src-template/entity.ftl +++ b/DaoGenerator/src-template/entity.ftl @@ -187,7 +187,7 @@ ${keepFields!} // KEEP FIELDS END <#if entity.propertiesPk?has_content && entity.propertiesPk?size != entity.properties?size> public ${entity.className}(<#list entity.propertiesPk as -property>${property.javaType} ${property.propertyName}<#if property_has_next>, ) { +property>${property.javaTypeInEntity} ${property.propertyName}<#if property_has_next>, ) { <#list entity.propertiesPk as property> this.${property.propertyName} = ${property.propertyName}; diff --git a/DaoGenerator/src/org/greenrobot/greendao/generator/Entity.java b/DaoGenerator/src/org/greenrobot/greendao/generator/Entity.java index 1264d6273..52f5d3c91 100644 --- a/DaoGenerator/src/org/greenrobot/greendao/generator/Entity.java +++ b/DaoGenerator/src/org/greenrobot/greendao/generator/Entity.java @@ -530,7 +530,9 @@ void init2ndPass() { if (propertiesPk.size() == 1) { pkProperty = propertiesPk.get(0); - pkType = schema.mapToJavaTypeNullable(pkProperty.getPropertyType()); + pkType = pkProperty.getCustomTypeClassName() != null ? + pkProperty.getCustomTypeClassName() : + schema.mapToJavaTypeNullable(pkProperty.getPropertyType()); } else { pkType = "Void"; } diff --git a/tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/entity/CustomPkTypeEntityTest.java b/tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/entity/CustomPkTypeEntityTest.java new file mode 100644 index 000000000..62ca01fdd --- /dev/null +++ b/tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/entity/CustomPkTypeEntityTest.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org) + * + * This file is part of greenDAO Generator. + * + * greenDAO Generator is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * greenDAO Generator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with greenDAO Generator. If not, see . + */ + +package org.greenrobot.greendao.daotest.entity; + +import org.greenrobot.greendao.daotest.CustomPkTypeEntity; +import org.greenrobot.greendao.daotest.CustomPkTypeEntityDao; +import org.greenrobot.greendao.test.AbstractDaoTestSinglePk; + +import java.util.List; +import java.util.UUID; + +public class CustomPkTypeEntityTest extends AbstractDaoTestSinglePk { + + public CustomPkTypeEntityTest() { + super(CustomPkTypeEntityDao.class); + } + + @Override + protected CustomPkTypeEntity createEntity(UUID key) { + CustomPkTypeEntity entity = new CustomPkTypeEntity(); + entity.setId(key); + return entity; + } + + @Override + protected UUID createRandomPk() { + return UUID.randomUUID(); + } + + public void testCustomPkTypeValue() { + CustomPkTypeEntity entity = createEntityWithRandomPk(); + UUID id = entity.getId(); + dao.insert(entity); + + List all = dao.loadAll(); + assertEquals(1, all.size()); + assertEquals(id, all.get(0).getId()); + } + + public void testCustomPkTypeValueNull() { + CustomPkTypeEntity entity = createEntityWithRandomPk(); + entity.setId(null); + dao.insert(entity); + + List all = dao.loadAll(); + assertEquals(1, all.size()); + assertNull(all.get(0).getId()); + } +} diff --git a/tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/CustomPkTypeEntity.java b/tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/CustomPkTypeEntity.java new file mode 100644 index 000000000..5b15a8621 --- /dev/null +++ b/tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/CustomPkTypeEntity.java @@ -0,0 +1,50 @@ +package org.greenrobot.greendao.daotest; + +import org.greenrobot.greendao.annotation.*; + +import java.util.UUID; + +// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT. Enable "keep" sections if you want to edit. + +/** + * Entity mapped to table "CUSTOM_PK_TYPE_ENTITY". + */ +@Entity +public class CustomPkTypeEntity { + + @Id + @Convert(converter = org.greenrobot.greendao.daotest.customtype.UuidConverter.class, columnType = String.class) + private UUID id; + private Integer value; + + @Generated + public CustomPkTypeEntity() { + } + + public CustomPkTypeEntity(UUID id) { + this.id = id; + } + + @Generated + public CustomPkTypeEntity(UUID id, Integer value) { + this.id = id; + this.value = value; + } + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public Integer getValue() { + return value; + } + + public void setValue(Integer value) { + this.value = value; + } + +} diff --git a/tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/CustomPkTypeEntityDao.java b/tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/CustomPkTypeEntityDao.java new file mode 100644 index 000000000..999b42a9e --- /dev/null +++ b/tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/CustomPkTypeEntityDao.java @@ -0,0 +1,130 @@ +package org.greenrobot.greendao.daotest; + +import android.database.Cursor; +import android.database.sqlite.SQLiteStatement; + +import org.greenrobot.greendao.AbstractDao; +import org.greenrobot.greendao.Property; +import org.greenrobot.greendao.internal.DaoConfig; +import org.greenrobot.greendao.database.Database; +import org.greenrobot.greendao.database.DatabaseStatement; + +import java.util.UUID; +import org.greenrobot.greendao.daotest.customtype.UuidConverter; + +// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT. +/** + * DAO for table "CUSTOM_PK_TYPE_ENTITY". +*/ +public class CustomPkTypeEntityDao extends AbstractDao { + + public static final String TABLENAME = "CUSTOM_PK_TYPE_ENTITY"; + + /** + * Properties of entity CustomPkTypeEntity.
+ * Can be used for QueryBuilder and for referencing column names. + */ + public static class Properties { + public final static Property Id = new Property(0, String.class, "id", true, "ID"); + public final static Property Value = new Property(1, Integer.class, "value", false, "VALUE"); + } + + private final UuidConverter idConverter = new UuidConverter(); + + public CustomPkTypeEntityDao(DaoConfig config) { + super(config); + } + + public CustomPkTypeEntityDao(DaoConfig config, DaoSession daoSession) { + super(config, daoSession); + } + + /** Creates the underlying database table. */ + public static void createTable(Database db, boolean ifNotExists) { + String constraint = ifNotExists? "IF NOT EXISTS ": ""; + db.execSQL("CREATE TABLE " + constraint + "\"CUSTOM_PK_TYPE_ENTITY\" (" + // + "\"ID\" TEXT PRIMARY KEY NOT NULL ," + // 0: id + "\"VALUE\" INTEGER);"); // 1: value + } + + /** Drops the underlying database table. */ + public static void dropTable(Database db, boolean ifExists) { + String sql = "DROP TABLE " + (ifExists ? "IF EXISTS " : "") + "\"CUSTOM_PK_TYPE_ENTITY\""; + db.execSQL(sql); + } + + @Override + protected final void bindValues(DatabaseStatement stmt, CustomPkTypeEntity entity) { + stmt.clearBindings(); + + UUID id = entity.getId(); + if (id != null) { + stmt.bindString(1, idConverter.convertToDatabaseValue(id)); + } + + Integer value = entity.getValue(); + if (value != null) { + stmt.bindLong(2, value); + } + } + + @Override + protected final void bindValues(SQLiteStatement stmt, CustomPkTypeEntity entity) { + stmt.clearBindings(); + + UUID id = entity.getId(); + if (id != null) { + stmt.bindString(1, idConverter.convertToDatabaseValue(id)); + } + + Integer value = entity.getValue(); + if (value != null) { + stmt.bindLong(2, value); + } + } + + @Override + public UUID readKey(Cursor cursor, int offset) { + return cursor.isNull(offset + 0) ? null : idConverter.convertToEntityProperty(cursor.getString(offset + 0)); + } + + @Override + public CustomPkTypeEntity readEntity(Cursor cursor, int offset) { + CustomPkTypeEntity entity = new CustomPkTypeEntity( // + cursor.isNull(offset + 0) ? null : idConverter.convertToEntityProperty(cursor.getString(offset + 0)), // id + cursor.isNull(offset + 1) ? null : cursor.getInt(offset + 1) // value + ); + return entity; + } + + @Override + public void readEntity(Cursor cursor, CustomPkTypeEntity entity, int offset) { + entity.setId(cursor.isNull(offset + 0) ? null : idConverter.convertToEntityProperty(cursor.getString(offset + 0))); + entity.setValue(cursor.isNull(offset + 1) ? null : cursor.getInt(offset + 1)); + } + + @Override + protected final UUID updateKeyAfterInsert(CustomPkTypeEntity entity, long rowId) { + return entity.getId(); + } + + @Override + public UUID getKey(CustomPkTypeEntity entity) { + if(entity != null) { + return entity.getId(); + } else { + return null; + } + } + + @Override + public boolean hasKey(CustomPkTypeEntity entity) { + return entity.getId() != null; + } + + @Override + protected final boolean isEntityUpdateable() { + return true; + } + +} diff --git a/tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/DaoMaster.java b/tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/DaoMaster.java index c50b4d527..458321baa 100644 --- a/tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/DaoMaster.java +++ b/tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/DaoMaster.java @@ -37,6 +37,7 @@ public static void createAllTables(Database db, boolean ifNotExists) { StringKeyValueEntityDao.createTable(db, ifNotExists); AutoincrementEntityDao.createTable(db, ifNotExists); CustomTypeEntityDao.createTable(db, ifNotExists); + CustomPkTypeEntityDao.createTable(db, ifNotExists); IndexedStringEntityDao.createTable(db, ifNotExists); } @@ -58,6 +59,7 @@ public static void dropAllTables(Database db, boolean ifExists) { StringKeyValueEntityDao.dropTable(db, ifExists); AutoincrementEntityDao.dropTable(db, ifExists); CustomTypeEntityDao.dropTable(db, ifExists); + CustomPkTypeEntityDao.dropTable(db, ifExists); IndexedStringEntityDao.dropTable(db, ifExists); } @@ -94,6 +96,7 @@ public DaoMaster(Database db) { registerDaoClass(AutoincrementEntityDao.class); registerDaoClass(SqliteMasterDao.class); registerDaoClass(CustomTypeEntityDao.class); + registerDaoClass(CustomPkTypeEntityDao.class); registerDaoClass(IndexedStringEntityDao.class); } diff --git a/tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/DaoSession.java b/tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/DaoSession.java index 19b0564c6..a84aa054f 100644 --- a/tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/DaoSession.java +++ b/tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/DaoSession.java @@ -25,6 +25,7 @@ import org.greenrobot.greendao.daotest.AutoincrementEntity; import org.greenrobot.greendao.daotest.SqliteMaster; import org.greenrobot.greendao.daotest.CustomTypeEntity; +import org.greenrobot.greendao.daotest.CustomPkTypeEntity; import org.greenrobot.greendao.daotest.IndexedStringEntity; import org.greenrobot.greendao.daotest.SimpleEntityDao; @@ -44,6 +45,7 @@ import org.greenrobot.greendao.daotest.AutoincrementEntityDao; import org.greenrobot.greendao.daotest.SqliteMasterDao; import org.greenrobot.greendao.daotest.CustomTypeEntityDao; +import org.greenrobot.greendao.daotest.CustomPkTypeEntityDao; import org.greenrobot.greendao.daotest.IndexedStringEntityDao; // THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT. @@ -72,6 +74,7 @@ public class DaoSession extends AbstractDaoSession { private final DaoConfig autoincrementEntityDaoConfig; private final DaoConfig sqliteMasterDaoConfig; private final DaoConfig customTypeEntityDaoConfig; + private final DaoConfig customPkTypeEntityDaoConfig; private final DaoConfig indexedStringEntityDaoConfig; private final SimpleEntityDao simpleEntityDao; @@ -91,6 +94,7 @@ public class DaoSession extends AbstractDaoSession { private final AutoincrementEntityDao autoincrementEntityDao; private final SqliteMasterDao sqliteMasterDao; private final CustomTypeEntityDao customTypeEntityDao; + private final CustomPkTypeEntityDao customPkTypeEntityDao; private final IndexedStringEntityDao indexedStringEntityDao; public DaoSession(Database db, IdentityScopeType type, Map>, DaoConfig> @@ -148,6 +152,9 @@ public DaoSession(Database db, IdentityScopeType type, Map { + @Override + public UUID convertToEntityProperty(String databaseValue) { + return UUID.fromString(databaseValue); + } + + @Override + public String convertToDatabaseValue(UUID entityProperty) { + return entityProperty.toString(); + } +} diff --git a/tests/DaoTestGenerator/src/org/greenrobot/greendao/generator/gentest/TestDaoGenerator.java b/tests/DaoTestGenerator/src/org/greenrobot/greendao/generator/gentest/TestDaoGenerator.java index 87f95f758..00b8c4f05 100644 --- a/tests/DaoTestGenerator/src/org/greenrobot/greendao/generator/gentest/TestDaoGenerator.java +++ b/tests/DaoTestGenerator/src/org/greenrobot/greendao/generator/gentest/TestDaoGenerator.java @@ -61,6 +61,7 @@ public TestDaoGenerator() { createAutoincrement(); createSqliteMaster(); createCustomType(); + createCustomPkTypeEntity(); createIndexedString(); schema2 = createSchema2(); @@ -104,6 +105,12 @@ protected void createSimpleNotNull() { notNull.addByteArrayProperty("simpleByteArray").notNull(); } + protected void createCustomPkTypeEntity() { + Entity entity = schema.addEntity("CustomPkTypeEntity"); + entity.addStringProperty("id").customType("java.util.UUID", "org.greenrobot.greendao.daotest.customtype.UuidConverter").primaryKey(); + entity.addIntProperty("value"); + } + protected Entity createTest() { Entity testEntity = schema.addEntity("TestEntity"); testEntity.setJavaDoc("This entity is used by internal tests of greenDAO.\n" +