-
Notifications
You must be signed in to change notification settings - Fork 581
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Possible to change SugarRecord 'id' variable to '_id' or 'mId'? #380
Comments
+1 |
@Psest328 you should try to use TypeAdapter and/or TypeAdapterFactory We can rethink how Sugar creates the default ID column |
@Psest328, Is possible create one notation for mark the id and change the sugarRecord class to use this over fixed pk. |
@diogosq, what I'm doing now is just changing the 'id' field in the json data to '_id' before parsing it with gson, so it's a minor workaround. But considering how common 'id' is, I'd like to see sugar maybe change theirs to 'sugarId' to avoid parsing conflicts |
@sibeliusseraphini yes, of course. package br.com.orm.dsl;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* Notation to set primary key field in Sugar entities
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface PrimaryKey {
}
public class SugarRecord<T> {
....
/**
* Delete T extends SugarRecord object
*
* @param object
* @param <T>
* @return
*/
@SuppressWarnings("JavaDoc")
public static <T extends SugarRecord<?>> boolean delete(T object) {
boolean deleted;
Long id;
Field field;
try {
field = findPrimaryKeyNotationField(object.getClass());
field.setAccessible(true);
id = (Long) field.get(object);
if (id != null && id > 0L) {
deleted = getOpenSugarDb().delete(getTableName(object.getClass()),
StringUtil.toSQLName(findPrimaryKeyNotation(object.getClass())) + "=?",
new String[]{id.toString()}) == 1;
LOGGER.debug(object.getClass().getSimpleName(), " deleted : ", id);
} else {
LOGGER.debug("Cannot delete object: ", object.getClass().getSimpleName(),
" - object has not been saved");
deleted = false;
}
} catch (IllegalAccessException e) {
LOGGER.debug(e, "Cannot delete object: ", object.getClass().getSimpleName(), " - can't access id");
throw new ORMException(e);
} finally {
closeDatabase();
}
return deleted;
}
/**
* List all registers of table of class T
*
* @param type
* @param <T>
* @return
*/
@SuppressWarnings("JavaDoc")
public static <T extends SugarRecord<?>> List<T> listAll(Class<T> type) {
return find(type, null, null, null, null, null);
}
/**
* Find location of parameter using @PrimaryKey notation
*
* @param type
* @return
*/
@SuppressWarnings("JavaDoc")
private static int findPrimaryKeyNotationLocation(Class type) {
int primaryKeyFieldLocation = -1;
int i = -1;
Field[] fields = type.getDeclaredFields();
for (Field field : fields) {
i += 1;
if (!field.isAnnotationPresent(Ignore.class) && !Modifier.isStatic(field.getModifiers()) &&
!Modifier.isTransient(field.getModifiers())) {
if (field.isAnnotationPresent(PrimaryKey.class)) {
primaryKeyFieldLocation = i;
}
}
}
return primaryKeyFieldLocation;
}
/**
* Find name of parameter using @PrimaryKey notation
*
* @param type
* @return
*/
@SuppressWarnings("JavaDoc")
public static String findPrimaryKeyNotation(Class type) {
Field pk = findPrimaryKeyNotationField(type);
return pk == null ? null : pk.getName();
}
/**
* Find field of parameter using @PrimaryKey notation
*
* @param type
* @return
*/
@SuppressWarnings("JavaDoc")
private static Field findPrimaryKeyNotationField(Class type) {
Field primaryField = null;
Field[] fields = type.getDeclaredFields();
for (Field field : fields) {
if (!field.isAnnotationPresent(Ignore.class) &&
!Modifier.isStatic(field.getModifiers()) &&
!Modifier.isTransient(field.getModifiers())) {
if (field.isAnnotationPresent(PrimaryKey.class)) {
primaryField = field;
}
}
}
return primaryField;
}
/**
* Find register in table of class T using id
*
* @param type
* @param id
* @param <T>
* @return
*/
@SuppressWarnings("JavaDoc")
public static <T extends SugarRecord<?>> T findById(Class<T> type, Long id) {
String primaryKeyFieldName = findPrimaryKeyNotation(type);
String pk = StringUtil.toSQLName(primaryKeyFieldName);
List<T> list = find(type, pk + "=?", new String[]{String.valueOf(id)}, null, null, "1");
return list.isEmpty() ? null : list.get(0);
}
...
/**
* Delete register of table of this object class using id parameter for primary key
*
* @param id pk value
*/
public void delete(Long id) {
try {
getOpenSugarDb().delete(this.TABLE_NAME, StringUtil.toSQLName(findPrimaryKeyNotation(getClass())) + "=?",
new String[]{String.valueOf(id)});
} finally {
closeDatabase();
}
}
/**
* Save register in table of this object class
*/
public void save() {
try {
save(getOpenSugarDb());
} finally {
closeDatabase();
}
}
/**
* Save register in table of this object class using database db
*
* @param db
*/
@SuppressWarnings("IfStatementWithTooManyBranches JavaDoc")
public void save(SQLiteDatabase db) {
List<Field> columns = getTableFields();
ContentValues values = new ContentValues(columns.size());
try {
for (Field column : columns) {
column.setAccessible(true);
if (!column.isAnnotationPresent(Ignore.class)) {
if (column.isAnnotationPresent(PrimaryKey.class)) {
setValueFromPrimaryKey(values, column);
} else if (column.isAnnotationPresent(Enumerated.class)) {
setValueFromEnumerated(values, column);
} else if (column.isAnnotationPresent(ForeignKey.class)) {
setValueFromForeignKey(values, column);
} else {
setValue(values, column);
}
}
}
} catch (Exception e) {
LOGGER.error(e, e.getMessage());
throw new EntityNotFoundException(e);
}
insertOrUpdate(db, values);
}
/**
* @param values
* @param column
* @throws IllegalAccessException
*/
@SuppressWarnings("JavaDoc")
private void setValueFromPrimaryKey(ContentValues values, Field column) throws IllegalAccessException {
String columnName = StringUtil.toSQLName(column.getName());
Class<?> columnType = column.getType();
Object columnValue = column.get(this);
column.setAccessible(true);
if (columnType.equals(Integer.class) || columnType.equals(int.class)) {
values.put(columnName, (Integer) columnValue);
} else if (columnType.equals(Long.class) || columnType.equals(long.class)) {
values.put(columnName, (Long) columnValue);
}
}
/**
* Insert or update
*
* @param db
* @param values
*/
private void insertOrUpdate(SQLiteDatabase db, ContentValues values) {
String primaryKeyFieldName = findPrimaryKeyNotation(getClass());
Long pkvalue = (Long) values.get(StringUtil.toSQLName(primaryKeyFieldName));
Field pkField;
if (pkvalue == null) {
pkvalue = db.insertOrThrow(getSqlName(), null, values);
try {
pkField = getClass().getDeclaredField(primaryKeyFieldName);
pkField.setAccessible(true);
pkField.set(this, pkvalue);
} catch (Exception e) {
LOGGER.error(e, "Error in insert of primary key to objeto in db");
throw new ORMException(e);
}
} else {
if (TextUtils.isEmpty(primaryKeyFieldName)) {
primaryKeyFieldName = findPrimaryKeyNotation(getClass());
}
db.update(getSqlName(), values, StringUtil.toSQLName(primaryKeyFieldName).concat(" = ?"), new String[]{String.valueOf(pkvalue)});
}
LOGGER.debug(getClass().getSimpleName(), " saved : ", pkvalue);
}
/**
* Set java native values
*
* @param values o contentvalues do sqlite
* @param column a coluna da classe a ser buscada
* @throws IllegalAccessException
*/
@SuppressWarnings("IfStatementWithTooManyBranches")
private void setValue(ContentValues values, Field column) throws IllegalAccessException {
String columnName = StringUtil.toSQLName(column.getName());
Class<?> columnType = column.getType();
Object columnValue = column.get(this);
if (!SugarRecord.class.isAssignableFrom(columnType)) {
if (columnType.equals(Short.class) || columnType.equals(short.class)) {
values.put(columnName, (Short) columnValue);
} else if (columnType.equals(Integer.class) || columnType.equals(int.class)) {
values.put(columnName, (Integer) columnValue);
} else if (columnType.equals(Long.class) || columnType.equals(long.class)) {
values.put(columnName, (Long) columnValue);
} else if (columnType.equals(Float.class) || columnType.equals(float.class)) {
values.put(columnName, (Float) columnValue);
} else if (columnType.equals(Double.class) || columnType.equals(double.class)) {
values.put(columnName, (Double) columnValue);
} else if (columnType.equals(Boolean.class) || columnType.equals(boolean.class)) {
values.put(columnName, (Boolean) columnValue);
} else if (Date.class.equals(columnType)) {
Object date = column.get(this);
if (date != null) {
values.put(columnName, ((Date) date).getTime());
}
} else if (Calendar.class.equals(columnType)) {
values.put(columnName, ((Calendar) column.get(this)).getTimeInMillis());
} else {
values.put(columnName, String.valueOf(columnValue));
}
}
}
/**
* Inflate registers of table in field set
*
* @param cursor
*/
@SuppressWarnings("IfStatementWithTooManyBranches JavaDoc")
public void inflate(Cursor cursor) {
List<Field> columns = getTableFields();
try {
for (Field column : columns) {
column.setAccessible(true);
String colName = getNameColumn(column);
int columnIndex = cursor.getColumnIndex(colName);
if (!cursor.isNull(columnIndex) && !column.isAnnotationPresent(Ignore.class)) {
if (column.isAnnotationPresent(PrimaryKey.class)) {
columnSetPrimaryKey(cursor, column);
} else if (column.isAnnotationPresent(ForeignKey.class)) {
columnSetForeignKey(cursor, column);
} else if (column.isAnnotationPresent(Enumerated.class)) {
columnSetEnum(cursor, column);
} else {
columnSet(cursor, column);
}
}
}
} catch (Exception e) {
LOGGER.error(e, " field set error ", e.getMessage());
throw new MappingException("O enums nao existe um tipo associado");
}
}
/**
* Find database collumn name
*
* @param column
* @return
*/
private String getNameColumn(Field column) {
String nameColumn = StringUtil.toSQLName(column.getName());
if (column.isAnnotationPresent(ForeignKey.class)) {
ForeignKey foreignKey = column.getAnnotation(ForeignKey.class);
nameColumn = foreignKey.name();
}
return nameColumn;
}
/**
* Associa a entidade na coluna primarykey o valor relacionado no cursor
*
* @param cursor o cursor da consulta
* @param column a coluna do tipo primarykey
* @throws IllegalAccessException caso aconteca um erro ao setar o valor do objeto
*/
private void columnSetPrimaryKey(Cursor cursor, Field column) throws IllegalAccessException {
int columnIndex = cursor.getColumnIndex(StringUtil.toSQLName(column.getName()));
Class<?> fieldType = column.getType();
if (fieldType.equals(long.class) || fieldType.equals(Long.class)) {
column.set(this, cursor.getLong(columnIndex));
} else if (fieldType.equals(int.class) || fieldType.equals(Integer.class)) {
column.set(this, cursor.getInt(columnIndex));
}
}
/**
* Associa a entidade na coluna com valores genericos o valor relacionado no cursor
*
* @param cursor o cursor da consulta
* @param column a coluna com os tipos dos objetos
* @throws IllegalAccessException caso aconteca um erro ao setar o valor do objeto
*/
@SuppressWarnings("IfStatementWithTooManyBranches")
private void columnSet(Cursor cursor, Field column) throws IllegalAccessException {
int columnIndex = cursor.getColumnIndex(StringUtil.toSQLName(column.getName()));
Class<?> fieldType = column.getType();
if (fieldType.equals(long.class) || fieldType.equals(Long.class)) {
column.set(this, cursor.getLong(columnIndex));
} else if (fieldType.equals(String.class)) {
String val = cursor.getString(columnIndex);
column.set(this, val != null && val.equals("null") ? null : val);
} else if (fieldType.equals(double.class) || fieldType.equals(Double.class)) {
column.set(this, cursor.getDouble(columnIndex));
} else if (fieldType.equals(boolean.class) || fieldType.equals(Boolean.class)) {
column.set(this, cursor.getString(columnIndex).equals("1"));
} else if (fieldType.getName().equals("[B")) {
column.set(this, cursor.getBlob(columnIndex));
} else if (fieldType.equals(int.class) || fieldType.equals(Integer.class)) {
column.set(this, cursor.getInt(columnIndex));
} else if (fieldType.equals(float.class) || fieldType.equals(Float.class)) {
column.set(this, cursor.getFloat(columnIndex));
} else if (fieldType.equals(short.class) || fieldType.equals(Short.class)) {
column.set(this, cursor.getShort(columnIndex));
} else if (fieldType.equals(Timestamp.class)) {
column.set(this, new Timestamp(cursor.getLong(columnIndex)));
} else if (fieldType.equals(Date.class)) {
column.set(this, new Date(cursor.getLong(columnIndex)));
} else if (fieldType.equals(Calendar.class)) {
column.set(this, new Date(cursor.getLong(columnIndex)).getTime());
}
}
.... |
@sibeliusseraphini Enumerated.java |
@diogosq this is great! are you willing to submit a PR with this modifications? I will be glad to merge your changes into master, we just need to make sure this changes don't break anything could you please also check whether there are more issues that will be solved by this PR? |
@sibeliusseraphini Thanks! Yes, I can submit a pull request. But, my fork have some personal class. I need clean the SugarRecord before. Maybe in this week I can make this. In really, the SugarRecord have some modifications what I can't ensure 100% of compatibility. Anyway, I will make a PR. |
@sibeliusseraphini I submit a pk #490 |
I'm not sure Sugar ORM should try and fix this, as it's really a problem with a bad server implementation. |
In issue #491 I post the solution I have found after dealing with the same problem. The best approach it's to create an ExclusionStrategy for Gson. |
Sorry if this is a really annoying request, but I'm getting json data returned from 3 servers. All 3 bundles of data contain an 'id' field. I'm using sugar alongside gson, but since the class extends SugarRecord, gson is trying to assign the value of 'id' from the json to SugarRecord's 'id' rather than my class'.
considering the 'id' field in sugar is protected anyway, is it possible to change the variable's name?
The text was updated successfully, but these errors were encountered: