/** * Return the instance of an entity with a matching id. * * @param <T> Any ActiveRecordBase class. * @param type The class of the entity to return. * @param id The desired ID. * @return The matching entity if reocrd found in DB, null otherwise * @throws ActiveRecordException */ public <T extends ActiveRecordBase> T findByID(Class<T> type, long id) throws ActiveRecordException { if (m_Database == null) throw new ActiveRecordException("Set database first"); T entity = s_EntitiesMap.get(type, id); if (entity != null) return entity; try { entity = type.newInstance(); } catch (IllegalAccessException e) { throw new ActiveRecordException(e.getLocalizedMessage()); } catch (InstantiationException e) { throw new ActiveRecordException(e.getLocalizedMessage()); } Cursor c = m_Database.query(entity.getTableName(), null, "_id = ?", new String[] {String.valueOf(id)}); try { if (!c.moveToNext()) { return null; } else { entity.inflate(c); entity.m_NeedsInsert = false; entity.m_Database = m_Database; } } finally { c.close(); } return entity; }
/** * Return all instances of an entity that match the given criteria. Use whereClause to specify * condition, using reqular SQL syntax for WHERE clause. * * <p>For example selecting all JOHNs born in 2001 from USERS table may look like: * * <pre> * users.find(Users.class, "NAME='?' and YEAR=?", new String[] {"John", "2001"}); * </pre> * * @param <T> Any ActiveRecordBase class. * @param type The class of the entities to return. * @param whereClause The condition to match (Don't include "where"). * @param whereArgs The arguments to replace "?" with. * @return A generic list of all matching entities. * @throws IllegalArgumentException * @throws IllegalAccessException * @throws InstantiationException */ public <T extends ActiveRecordBase> List<T> find( Class<T> type, String whereClause, String[] whereArgs) throws ActiveRecordException { if (m_Database == null) throw new ActiveRecordException("Set database first"); T entity = null; try { entity = type.newInstance(); } catch (IllegalAccessException e1) { throw new ActiveRecordException(e1.getLocalizedMessage()); } catch (InstantiationException e1) { throw new ActiveRecordException(e1.getLocalizedMessage()); } List<T> toRet = new ArrayList<T>(); Cursor c = m_Database.query(entity.getTableName(), null, whereClause, whereArgs); try { while (c.moveToNext()) { entity = s_EntitiesMap.get(type, c.getLong(c.getColumnIndex("_id"))); if (entity == null) { entity = type.newInstance(); entity.m_Database = m_Database; entity.m_NeedsInsert = false; entity.inflate(c); } toRet.add(entity); } } catch (IllegalAccessException e) { throw new ActiveRecordException(e.getLocalizedMessage()); } catch (InstantiationException e) { throw new ActiveRecordException(e.getLocalizedMessage()); } finally { c.close(); } return toRet; }
/** * Saves this entity to the database, inserts or updates as needed. * * @return number of rows affected on success, -1 on failure * @throws ActiveRecordException */ public long save() throws ActiveRecordException { long r = -1; if (m_Database == null) throw new ActiveRecordException("Set database first"); if (null == findByID(this.getClass(), _id)) { if (insert() > 0) { r = 1; } } else { r = update(); } for (Field column : getColumnFields()) { if (column.getType() == List.class) { try { List<ActiveRecordBase> listObjects = (List<ActiveRecordBase>) column.get(this); Field itemOwner = null; if (listObjects != null && listObjects.size() > 0) { for (Field childColumn : listObjects.get(0).getColumnFields()) { // Try to find the parent column and set it // automatically to save time from those setters // and getters if (childColumn.getType() == this.getClass()) { itemOwner = childColumn; break; } } for (ActiveRecordBase item : listObjects) { if (item.getDatabase() == null) { item.setDatabase(getDatabase()); } if (itemOwner != null) { itemOwner.set(item, this); } item.save(); } } } catch (IllegalAccessException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } } } s_EntitiesMap.set(this); return r; }
/** * Inflate this entity using the current row from the given cursor. * * @param cursor The cursor to get object data from. * @throws IllegalArgumentException * @throws IllegalAccessException * @throws InstantiationException */ @SuppressWarnings("unchecked") void inflate(Cursor cursor) throws ActiveRecordException { HashMap<Field, Long> entities = new HashMap<Field, Long>(); for (Field field : getColumnFields()) { try { String typeString = field.getType().getName(); String colName = CamelNotationHelper.toSQLName(field.getName()); if (typeString.equals("long")) { field.setLong(this, cursor.getLong(cursor.getColumnIndex(colName))); } else if (typeString.equals("java.lang.String")) { String val = cursor.getString(cursor.getColumnIndex(colName)); field.set(this, val.equals("null") ? null : val); } else if (typeString.equals("double")) { field.setDouble(this, cursor.getDouble(cursor.getColumnIndex(colName))); } else if (typeString.equals("boolean")) { field.setBoolean(this, cursor.getString(cursor.getColumnIndex(colName)).equals("true")); } else if (typeString.equals("[B")) { field.set(this, cursor.getBlob(cursor.getColumnIndex(colName))); } else if (typeString.equals("int")) { field.setInt(this, cursor.getInt(cursor.getColumnIndex(colName))); } else if (typeString.equals("float")) { field.setFloat(this, cursor.getFloat(cursor.getColumnIndex(colName))); } else if (typeString.equals("short")) { field.setShort(this, cursor.getShort(cursor.getColumnIndex(colName))); } else if (typeString.equals("java.sql.Timestamp")) { long l = cursor.getLong(cursor.getColumnIndex(colName)); field.set(this, new Timestamp(l)); } else if (field.getType().getSuperclass() == ActiveRecordBase.class) { long id = cursor.getLong(cursor.getColumnIndex(colName)); if (id > 0) entities.put(field, id); else field.set(this, null); } else if (field.getType() == List.class) { String classKey = field.getName(); // hack classKey = classKey.replaceFirst( "" + classKey.charAt(0), "" + Character.toUpperCase(classKey.charAt(0))); if (field.getName().endsWith("s")) { classKey = classKey.substring(0, classKey.length() - 1); } DatabaseBuilder ownBuilder = getDatabase().getOwnBuilder(); Class fieldClass = ownBuilder.getClassForName(classKey); if (fieldClass != null) { List<ActiveRecordBase> ownObjects = (List<ActiveRecordBase>) findByColumn( fieldClass, CamelNotationHelper.toSQLName(getTableName()), Long.toString(getID())); field.set(this, ownObjects); } } else if (field.getAnnotation(ActiveRecordIgnoreAttribute.class) != null) { continue; } else throw new ActiveRecordException( field.getName() + " of type " + field.getType() + " cannot be read from Sqlite3 database."); } catch (IllegalArgumentException e) { throw new ActiveRecordException(e.getLocalizedMessage()); } catch (IllegalAccessException e) { throw new ActiveRecordException(e.getLocalizedMessage()); } } s_EntitiesMap.set(this); for (Field f : entities.keySet()) { try { f.set( this, this.findByID((Class<? extends ActiveRecordBase>) f.getType(), entities.get(f))); } catch (SQLiteException e) { throw new ActiveRecordException(e.getLocalizedMessage()); } catch (IllegalArgumentException e) { throw new ActiveRecordException(e.getLocalizedMessage()); } catch (IllegalAccessException e) { throw new ActiveRecordException(e.getLocalizedMessage()); } } }