예제 #1
0
 /**
  * ** Returns true if this key fully defines all key fields ** @return True if this key fully
  * defines all key fields
  */
 public boolean isFullKey() {
   DBField kfld[] = this.getKeyFields();
   if (ListTools.isEmpty(kfld)) {
     return false;
   } else {
     DBFieldValues fldVals = this.getFieldValues(); // hasPartialKey
     for (int i = 0; i < kfld.length; i++) {
       String fldName = kfld[i].getName();
       if (!fldVals.hasFieldValue(fldName)) {
         return false;
       }
     }
     return true;
   }
 }
예제 #2
0
  /**
   * ** Return the 'WHERE' clause for this key [CHECK] ** @param altIndexName The alternate index
   * name. If null or blank, uses ** primary keys instead ** @param whereKeyType The where key type.
   * One of the constants from DBWhere ** @return The 'WHERE' clause for this key
   */
  protected String _getWhereClause(
      String altIndexName, int whereKeyType) // boolean fullKeyRequired)
      throws DBException {

    /* key fields */
    boolean usePrimaryKey = StringTools.isBlank(altIndexName);
    DBField keyFlds[] = usePrimaryKey ? this.getKeyFields() : this.getAltKeyFields(altIndexName);
    if (ListTools.isEmpty(keyFlds)) {
      throw new DBException("No keys found!");
    }

    /* WHERE */
    DBWhere dwh = new DBWhere(this.getFactory());
    DBFieldValues fldVals = this.getFieldValues();
    int keyCnt = 0;
    boolean hasPartialKey = false;
    for (int i = 0; i < keyFlds.length; i++) {
      String fldName = keyFlds[i].getName();
      if (fldVals.hasFieldValue(fldName)) {
        if (!hasPartialKey || (whereKeyType == DBWhere.KEY_PARTIAL_ALL)) {
          String fev = dwh.EQ(fldName, fldVals.getFieldValueAsString(fldName));
          if (keyCnt > 0) {
            dwh.append(dwh.AND_(fev));
          } else {
            dwh.append(fev);
          }
          keyCnt++;
        } else {
          // whereKeyType == DBWhere.KEY_PARTIAL_FIRST, and we found a subsequent key
          String m =
              "Additional partial key in 'WHERE' clause! ["
                  + this.getTableName()
                  + "."
                  + fldName
                  + "]";
          // throw new DBException(m); // TODO:
          Print.logWarn("******************************************************************");
          Print.logWarn(m);
          // Print.logWarn(StringTools.join(keyFlds,","));
          // Print.logStackTrace(m);
          Print.logWarn("******************************************************************");
        }
      } else if ((i == 0) && (whereKeyType != DBWhere.KEY_PARTIAL_ALL_EMPTY)) { //
        // missing first key
        if (keyFlds[i].isAutoIncrement()) {
          // first key is an "auto_increment" and it is not present
          // assume that we are expecting the DB server to create this value for us, thus the key
          // dow not exist
          // However, there is nothing we can do about this here.
          String m =
              "First key field for 'WHERE' clause is 'auto_increment' and field is not present ["
                  + this.getTableName()
                  + "."
                  + fldName
                  + "]";
          throw new DBException(m);
        } else {
          String m =
              "Missing first key field for 'WHERE' clause! ["
                  + this.getTableName()
                  + "."
                  + fldName
                  + "]";
          throw new DBException(m);
        }
      } else if (whereKeyType == DBWhere.KEY_FULL) {
        // missing a key when all keys are required
        String m = "Missing key for 'WHERE' clause! [" + this.getTableName() + "." + fldName + "]";
        throw new DBException(m);
      } else {
        // only a portion of the key has been specified.
        // This is a common occurance deleting an Account/Device with sub-dependencies
        // Print.logWarn("Key field not specified: " + this.getTableName() + "." + fldName);
        hasPartialKey = true;
      }
    }

    return (keyCnt > 1) ? dwh.WHERE(dwh.toString()) : dwh.WHERE_(dwh.toString());
  }
예제 #3
0
  /**
   * ** Returns true if the specified key attribute exists in the table ** @param altIndexName The
   * alternate index name, or null to use the primary index ** @param whereKeyType The partial key
   * match type ** @return True if the specified key attribute exists in the table, false otherwise
   */
  protected boolean _exists(String altIndexName, int whereKeyType)
      throws SQLException, DBException {

    /* key fields */
    boolean usePrimaryKey = StringTools.isBlank(altIndexName);
    DBField kfld[] = usePrimaryKey ? this.getKeyFields() : this.getAltKeyFields(altIndexName);
    if (ListTools.isEmpty(kfld)) {
      throw new DBException("No keys found!");
    }

    /* check last key for "auto_increment" */
    if (whereKeyType == DBWhere.KEY_FULL) {
      DBField lastField = kfld[kfld.length - 1];
      if (lastField.isAutoIncrement()
          && !this.getFieldValues().hasFieldValue(lastField.getName())) {
        // full key requested and last key is auto_increment, which is missing
        return false;
      }
    }

    // DBSelect: SELECT <Keys> FROM <TableName> <KeyWhere>
    String firstKey = kfld[0].getName();
    DBSelect<gDBR> dsel = new DBSelect<gDBR>(this.getFactory());
    dsel.setSelectedFields(firstKey);
    dsel.setWhere(this._getWhereClause(altIndexName, whereKeyType));

    /* get keyed record */
    DBConnection dbc = null;
    Statement stmt = null;
    ResultSet rs = null;
    boolean exists = false;
    try {
      dbc = DBConnection.getDefaultConnection();
      stmt = dbc.execute(dsel.toString()); // may throw DBException
      rs = stmt.getResultSet();
      exists = rs.next();
    } catch (SQLException sqe) {
      if (sqe.getErrorCode() == DBFactory.SQLERR_TABLE_NOTLOCKED) {
        // MySQL: This case has been seen on rare occasions.  Not sure what causes it.
        Print.logError("SQL Lock Error: " + sqe);
        Print.logError("Hackery! Forcing lock on table: " + this.getTableName());
        if (DBProvider.lockTableForRead(this.getTableName(), true)) { // may throw DBException
          stmt = dbc.execute(dsel.toString()); // may throw SQLException, DBException
          rs = stmt.getResultSet(); // SQLException
          exists = rs.next(); // SQLException
          DBProvider.unlockTables(); // DBException
        }
      } else {
        throw sqe;
      }
    } finally {
      if (rs != null) {
        try {
          rs.close();
        } catch (Throwable t) {
        }
      }
      if (stmt != null) {
        try {
          stmt.close();
        } catch (Throwable t) {
        }
      }
      DBConnection.release(dbc);
    }

    return exists;
  }
예제 #4
0
 /**
  * ** Returns true if any tagged field names have been defined ** @return True if any tagged field
  * names have been defined
  */
 public boolean hasTaggedFields() {
   return !ListTools.isEmpty(this.taggedFields);
 }