Example #1
0
  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);
          }
        }
      }
    }
  }
Example #2
0
  @SuppressWarnings("unchecked")
  @Nullable
  @CheckResult
  private RowType[] getInternal(int limit) {
    if (mRowClass == null) return null;
    else if (mInquiry.mContext == null) return null;
    if (mProjection == null) mProjection = ClassRowConverter.generateProjection(mRowClass);

    String sort = getSort();
    if (limit > -1) sort += String.format(Locale.getDefault(), " LIMIT %d", limit);
    Cursor cursor;
    if (mContentUri != null) {
      cursor =
          mInquiry
              .mContext
              .getContentResolver()
              .query(mContentUri, mProjection, getWhere(), getWhereArgs(), sort);
    } else {
      if (mInquiry.getDatabase() == null)
        throw new IllegalStateException("Database helper was null.");
      else if (mTableName == null) throw new IllegalStateException("Table name was null.");
      cursor =
          mInquiry.getDatabase().query(mTableName, mProjection, getWhere(), getWhereArgs(), sort);
    }

    if (cursor != null) {
      RowType[] results = null;
      if (cursor.getCount() > 0) {
        results = (RowType[]) Array.newInstance(mRowClass, cursor.getCount());
        int index = 0;
        while (cursor.moveToNext()) {
          results[index] = ClassRowConverter.cursorToCls(this, cursor, mRowClass);
          index++;
        }
      }
      cursor.close();
      return results;
    }
    return null;
  }
Example #3
0
  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);
    }
  }
Example #4
0
  @SuppressLint("SwitchIntDef")
  @SuppressWarnings("unchecked")
  public RunReturn run() {
    if (mQueryType != DELETE && (mValues == null || mValues.length == 0))
      throw new IllegalStateException("No values were provided for this query to run.");
    else if (mInquiry.mContext == null) {
      try {
        return (RunReturn) (Integer) 0;
      } catch (Throwable t) {
        return (RunReturn) (Long) 0L;
      }
    }

    final ContentResolver cr = mInquiry.mContext.getContentResolver();
    final List<Field> clsFields = ClassRowConverter.getAllFields(mRowClass);
    if (mTableName == null) throw new IllegalStateException("The table name cannot be null.");
    Field rowIdField = mInquiry.getIdField(mRowClass);

    try {
      switch (mQueryType) {
        case INSERT:
          Long[] insertedIds = new Long[mValues.length];
          if (mInquiry.getDatabase() != null) {
            for (int i = 0; i < mValues.length; i++) {
              final RowType row = mValues[i];
              if (row == null) continue;
              insertedIds[i] =
                  mInquiry
                      .getDatabase()
                      .insert(
                          mTableName,
                          ClassRowConverter.clsToVals(this, row, null, clsFields, false));
              ClassRowConverter.setIdField(row, rowIdField, insertedIds[i]);
            }
          } else if (mContentUri != null) {
            for (int i = 0; i < mValues.length; i++) {
              final RowType row = mValues[i];
              if (row == null) continue;
              final Uri uri =
                  cr.insert(
                      mContentUri, ClassRowConverter.clsToVals(this, row, null, clsFields, false));
              if (uri == null) return (RunReturn) (Long) (-1L);
              insertedIds[i] = Long.parseLong(uri.getLastPathSegment());
              ClassRowConverter.setIdField(row, rowIdField, insertedIds[i]);
            }
          } else throw new IllegalStateException("Database helper was null.");
          postRun(false);
          return (RunReturn) insertedIds;
        case UPDATE:
          {
            boolean allHaveIds = rowIdField != null;
            if (rowIdField != null && mValues != null) {
              for (RowType mValue : mValues) {
                if (mValue == null) continue;
                long id = ClassRowConverter.getRowId(mValue, rowIdField);
                if (id <= 0) {
                  allHaveIds = false;
                  break;
                }
              }
            }

            if (allHaveIds) {
              // We want to update each object as themselves
              if (getWhere() != null && !getWhere().trim().isEmpty()) {
                throw new IllegalStateException(
                    "You want to update rows which have IDs, but specified a where statement.");
              }

              int updatedCount = 0;
              for (RowType row : mValues) {
                if (row == null) continue;
                long rowId = ClassRowConverter.getRowId(row, rowIdField);
                ContentValues values =
                    ClassRowConverter.clsToVals(this, row, mProjection, clsFields, true);
                if (mInquiry.getDatabase() != null) {
                  updatedCount +=
                      mInquiry
                          .getDatabase()
                          .update(mTableName, values, "_id = ?", new String[] {rowId + ""});
                } else if (mContentUri != null) {
                  updatedCount +=
                      cr.update(mContentUri, values, "_id = ?", new String[] {rowId + ""});
                } else throw new IllegalStateException("Database helper was null.");
              }

              postRun(true);
              return (RunReturn) (Integer) updatedCount;
            }

            RowType firstNotNull = mValues[mValues.length - 1];
            if (firstNotNull == null) {
              for (int i = mValues.length - 2; i >= 0; i--) {
                firstNotNull = mValues[i];
                if (firstNotNull != null) break;
              }
            }
            if (firstNotNull == null)
              throw new IllegalStateException("No non-null values specified to update.");

            ContentValues values =
                ClassRowConverter.clsToVals(this, firstNotNull, mProjection, clsFields, true);
            if (mInquiry.getDatabase() != null) {
              RunReturn value =
                  (RunReturn)
                      (Integer)
                          mInquiry
                              .getDatabase()
                              .update(mTableName, values, getWhere(), getWhereArgs());
              postRun(true);
              return value;
            } else if (mContentUri != null)
              return (RunReturn)
                  (Integer) cr.update(mContentUri, values, getWhere(), getWhereArgs());
            else throw new IllegalStateException("Database helper was null.");
          }
        case DELETE:
          {
            Long[] idsToDelete = null;
            if (rowIdField != null && mValues != null) {
              int nonNullFound = 0;
              idsToDelete = new Long[mValues.length];
              for (int i = 0; i < mValues.length; i++) {
                if (mValues[i] == null) continue;
                nonNullFound++;
                long id = ClassRowConverter.getRowId(mValues[i], rowIdField);
                idsToDelete[i] = id;
                if (id <= 0) {
                  idsToDelete = null;
                  break;
                }
              }
              if (nonNullFound == 0) idsToDelete = null;
            }

            if (idsToDelete != null) {
              // We want to update each object as themselves
              if (getWhere() != null && !getWhere().trim().isEmpty()) {
                throw new IllegalStateException(
                    "You want to delete rows which have IDs, but specified a where statement.");
              }
              //noinspection CheckResult,ConfusingArgumentToVarargsMethod
              whereIn("_id", idsToDelete);
            }

            if (mInquiry.getDatabase() != null) {
              RunReturn value =
                  (RunReturn)
                      (Integer)
                          mInquiry.getDatabase().delete(mTableName, getWhere(), getWhereArgs());
              traverseDelete();
              return value;
            } else if (mContentUri != null)
              return (RunReturn) (Integer) cr.delete(mContentUri, getWhere(), getWhereArgs());
            else throw new IllegalStateException("Database helper was null.");
          }
      }
    } catch (Throwable t) {
      Utils.wrapInReIfNeccessary(t);
    }
    return null;
  }