private void traverseDelete() { RowType[] rowsThatWillDelete = all(); if (rowsThatWillDelete == null || rowsThatWillDelete.length == 0) return; List<Field> fields = ClassRowConverter.getAllFields(mRowClass); for (RowType row : rowsThatWillDelete) { for (Field fld : fields) { ForeignKey fkAnn = fld.getAnnotation(ForeignKey.class); if (fkAnn != null) { try { Field rowIdField = mInquiry.getIdField(mRowClass); if (rowIdField == null) throw new IllegalStateException("No _id column field found in " + mRowClass); Class<?> listGenericType = Utils.getGenericTypeOfField(fld); long rowId = rowIdField.getLong(row); Inquiry fkInstance = Inquiry.copy( mInquiry, "[@fk]:" + fkAnn.tableName() + "//" + fkAnn.foreignColumnName(), false); fkInstance .deleteFrom(fkAnn.tableName(), listGenericType) .where(fkAnn.foreignColumnName() + " = ?", rowId) .run(); fkInstance.destroyInstance(); } catch (Throwable t) { Utils.wrapInReIfNeccessary(t); } } } } }
private void postRun(boolean updateMode, Object row, Field fld) { try { ForeignKey fkAnn = fld.getAnnotation(ForeignKey.class); Object fldVal = fld.get(row); if (updateMode && Utils.classExtendsLazyLoader(fld.getType())) { LazyLoaderList lazyLoader = (LazyLoaderList) fldVal; if (!lazyLoader.didLazyLoad()) { // Lazy loading didn't happen, nothing was populated, so nothing changed return; } } Class<?> listGenericType = Utils.getGenericTypeOfField(fld); Field idField = mInquiry.getIdField(row.getClass()); Field fkIdField = mInquiry.getIdField(listGenericType); Field fkField = ClassRowConverter.getField( ClassRowConverter.getAllFields(listGenericType), fkAnn.foreignColumnName(), Long.class, long.class); if (idField == null) throw new IllegalStateException( "You cannot use the @ForeignKey annotation on a field within a class that doesn't have an _id column."); if (fkIdField == null) throw new IllegalStateException( "The @ForeignKey annotation can only be used on fields which contain class objects that have an _id column, " + listGenericType + " does not."); if (fkField == null) throw new IllegalStateException( "The @ForeignKey annotation on " + fld.getName() + " references a non-existent column (or a column which can't hold an Int64 ID): " + fkAnn.foreignColumnName()); long rowId = idField.getLong(row); if (rowId <= 0) throw new IllegalStateException( "The current row's ID is 0, you cannot insert/update @ForeignKey fields if the parent class has no ID."); List list = null; Object[] array = null; if (fldVal != null) { if (fld.getType().isArray()) array = (Object[]) fldVal; else if (Utils.classImplementsList(fld.getType())) list = (List) fldVal; else array = new Object[] {fldVal}; } Inquiry fkInstance = Inquiry.copy( mInquiry, "[@fk]:" + fkAnn.tableName() + "//" + fkAnn.foreignColumnName(), false); if ((array != null && array.length > 0) || (list != null && list.size() > 0)) { // Update foreign row columns with this row's ID if (array != null) { for (Object child : array) ClassRowConverter.setIdField(child, fkField, rowId); } else { for (int i = 0; i < list.size(); i++) ClassRowConverter.setIdField(list.get(i), fkField, rowId); } if (updateMode) { // Delete any rows in the foreign table which reference this row fkInstance .deleteFrom(fkAnn.tableName(), listGenericType) .where(fkAnn.foreignColumnName() + " = ?", rowId) .run(); } // Insert rows from this field into the foreign table if (array != null) { fkInstance.insertInto(fkAnn.tableName(), listGenericType).valuesArray(array).run(); } else { fkInstance.insertInto(fkAnn.tableName(), listGenericType).values(list).run(); } } else { // Delete any rows in the foreign table which reference this row fkInstance .deleteFrom(fkAnn.tableName(), listGenericType) .where(fkAnn.foreignColumnName() + " = ?", rowId) .run(); } fkInstance.destroyInstance(); } catch (Throwable t) { Utils.wrapInReIfNeccessary(t); } }