String createLOBSelectString(
      List<DbAttribute> selectedLOBAttributes, List<DbAttribute> qualifierAttributes) {

    QuotingStrategy strategy = adapter.getQuotingStrategy();

    StringBuilder buf = new StringBuilder();
    buf.append("SELECT ");

    Iterator<DbAttribute> it = selectedLOBAttributes.iterator();
    while (it.hasNext()) {
      buf.append(strategy.quotedName(it.next()));

      if (it.hasNext()) {
        buf.append(", ");
      }
    }

    buf.append(" FROM ")
        .append(strategy.quotedFullyQualifiedName(query.getDbEntity()))
        .append(" WHERE ");

    it = qualifierAttributes.iterator();
    while (it.hasNext()) {
      DbAttribute attribute = (DbAttribute) it.next();
      appendDbAttribute(buf, attribute);
      buf.append(" = ?");
      if (it.hasNext()) {
        buf.append(" AND ");
      }
    }

    buf.append(" FOR UPDATE");
    return buf.toString();
  }
 /** Adds the CASCADE option to the DROP TABLE clause. */
 @Override
 public Collection<String> dropTableStatements(DbEntity table) {
   QuotingStrategy context = getQuotingStrategy(table.getDataMap().isQuotingSQLIdentifiers());
   StringBuffer buf = new StringBuffer("DROP TABLE ");
   buf.append(context.quoteFullyQualifiedName(table));
   buf.append(" CASCADE");
   return Collections.singleton(buf.toString());
 }
  @Override
  protected String createSql() {

    QuotingStrategy strategy = adapter.getQuotingStrategy();

    StringBuilder buffer = new StringBuilder("DELETE FROM ");
    buffer.append(strategy.quotedFullyQualifiedName(query.getDbEntity()));

    applyQualifier(buffer);

    return buffer.toString();
  }
  public String createLOBSelectString(
      BatchQuery updateQuery, List selectedLOBAttributes, List qualifierAttributes) {

    boolean status;
    if (updateQuery.getDbEntity().getDataMap() != null
        && updateQuery.getDbEntity().getDataMap().isQuotingSQLIdentifiers()) {
      status = true;
    } else {
      status = false;
    }
    QuotingStrategy strategy = getAdapter().getQuotingStrategy(status);

    StringBuffer buf = new StringBuffer();
    buf.append("SELECT ");

    Iterator it = selectedLOBAttributes.iterator();
    while (it.hasNext()) {
      buf.append(strategy.quoteString(((DbAttribute) it.next()).getName()));

      if (it.hasNext()) {
        buf.append(", ");
      }
    }

    buf.append(" FROM ")
        .append(strategy.quoteFullyQualifiedName(updateQuery.getDbEntity()))
        .append(" WHERE ");

    it = qualifierAttributes.iterator();
    while (it.hasNext()) {
      DbAttribute attribute = (DbAttribute) it.next();
      appendDbAttribute(buf, attribute);
      buf.append(" = ?");
      if (it.hasNext()) {
        buf.append(" AND ");
      }
    }

    buf.append(" FOR UPDATE");
    return buf.toString();
  }
  /**
   * Customizes table creating procedure for PostgreSQL. One difference with generic implementation
   * is that "bytea" type has no explicit length unlike similar binary types in other databases.
   *
   * @since 1.0.2
   */
  @Override
  public String createTable(DbEntity ent) {
    boolean status;
    if (ent.getDataMap() != null && ent.getDataMap().isQuotingSQLIdentifiers()) {
      status = true;
    } else {
      status = false;
    }
    QuotingStrategy context = getQuotingStrategy(status);
    StringBuilder buf = new StringBuilder();
    buf.append("CREATE TABLE ");

    buf.append(context.quoteFullyQualifiedName(ent));

    buf.append(" (");

    // columns
    Iterator<DbAttribute> it = ent.getAttributes().iterator();
    boolean first = true;
    while (it.hasNext()) {
      if (first) first = false;
      else buf.append(", ");

      DbAttribute at = it.next();

      // attribute may not be fully valid, do a simple check
      if (at.getType() == TypesMapping.NOT_DEFINED) {
        throw new CayenneRuntimeException(
            "Undefined type for attribute '"
                + ent.getFullyQualifiedName()
                + "."
                + at.getName()
                + "'.");
      }

      String[] types = externalTypesForJdbcType(at.getType());
      if (types == null || types.length == 0) {
        throw new CayenneRuntimeException(
            "Undefined type for attribute '"
                + ent.getFullyQualifiedName()
                + "."
                + at.getName()
                + "': "
                + at.getType());
      }

      String type = types[0];
      buf.append(context.quoteString(at.getName())).append(' ').append(type);

      // append size and precision (if applicable)
      if (typeSupportsLength(at.getType())) {
        int len = at.getMaxLength();
        int scale =
            (TypesMapping.isDecimal(at.getType()) && at.getType() != Types.FLOAT) // Postgress
                // don't
                // support
                // notations
                // float(a,
                // b)
                ? at.getScale()
                : -1;

        // sanity check
        if (scale > len) {
          scale = -1;
        }

        if (len > 0) {
          buf.append('(').append(len);

          if (scale >= 0) {
            buf.append(", ").append(scale);
          }

          buf.append(')');
        }
      }

      if (at.isMandatory()) {
        buf.append(" NOT NULL");
      } else {
        buf.append(" NULL");
      }
    }

    // primary key clause
    Iterator<DbAttribute> pkit = ent.getPrimaryKeys().iterator();
    if (pkit.hasNext()) {
      if (first) first = false;
      else buf.append(", ");

      buf.append("PRIMARY KEY (");
      boolean firstPk = true;
      while (pkit.hasNext()) {
        if (firstPk) firstPk = false;
        else buf.append(", ");

        DbAttribute at = pkit.next();
        buf.append(context.quoteString(at.getName()));
      }
      buf.append(')');
    }
    buf.append(')');
    return buf.toString();
  }