/** * Update changes to the RDBMS. Note that if the update fails, the values in the row will NOT be * reverted. * * @param context Current DSpace context * @param row The row to update * @return The number of rows affected (1 or 0) * @exception SQLException If a database error occurs */ public static int update(Context context, TableRow row) throws SQLException { String table = row.getTable(); StringBuilder sql = new StringBuilder().append("update ").append(table).append(" set "); List<ColumnInfo> columns = new ArrayList<ColumnInfo>(); ColumnInfo pk = getPrimaryKeyColumnInfo(table); Collection<ColumnInfo> info = getColumnInfo(table); String separator = ""; for (ColumnInfo col : info) { // Only update this column if it has changed if (!col.isPrimaryKey()) { if (row.hasColumnChanged(col.getName())) { sql.append(separator).append(col.getName()).append(" = ?"); columns.add(col); separator = ", "; } } } // Only execute the update if there is anything to update if (columns.size() > 0) { sql.append(" where ").append(pk.getName()).append(" = ?"); columns.add(pk); return executeUpdate(context.getDBConnection(), sql.toString(), columns, row); } return 1; }
/** * Return column information for the primary key column, or null if the table has no primary key. * We assume there's only one primary key per table; if there are more, only the first one will be * returned. * * @param table The name of the RDBMS table * @return A ColumnInfo object, or null if the table has no primary key. * @exception SQLException If a database error occurs */ static ColumnInfo getPrimaryKeyColumnInfo(String table) throws SQLException { Collection<ColumnInfo> cinfo = getColumnInfo(canonicalize(table)); for (ColumnInfo info : cinfo) { if (info.isPrimaryKey()) { return info; } } return null; }
/** * Postgres-specific row insert, combining getnextid() and insert into single statement for * efficiency * * @param context * @param row * @return * @throws SQLException */ private static int doInsertPostgres(Context context, TableRow row) throws SQLException { String table = row.getTable(); Collection<ColumnInfo> info = getColumnInfo(table); Collection<ColumnInfo> params = new ArrayList<ColumnInfo>(); String primaryKey = getPrimaryKeyColumn(table); String sql = insertSQL.get(table); boolean firstColumn = true; boolean foundPrimaryKey = false; if (sql == null) { // Generate SQL and filter parameter columns StringBuilder insertBuilder = new StringBuilder("INSERT INTO ").append(table).append(" ( "); StringBuilder valuesBuilder = new StringBuilder(") VALUES ( "); for (ColumnInfo col : info) { if (firstColumn) { firstColumn = false; } else { insertBuilder.append(","); valuesBuilder.append(","); } insertBuilder.append(col.getName()); if (!foundPrimaryKey && col.isPrimaryKey()) { valuesBuilder.append("getnextid('").append(table).append("')"); foundPrimaryKey = true; } else { valuesBuilder.append('?'); params.add(col); } } sql = insertBuilder .append(valuesBuilder.toString()) .append(") RETURNING ") .append(getPrimaryKeyColumn(table)) .toString(); insertSQL.put(table, sql); } else { // Already have SQL, just filter parameter columns for (ColumnInfo col : info) { if (!foundPrimaryKey && col.isPrimaryKey()) { foundPrimaryKey = true; } else { params.add(col); } } } PreparedStatement statement = null; if (log.isDebugEnabled()) { log.debug("Running query \"" + sql + "\""); } ResultSet rs = null; try { statement = context.getDBConnection().prepareStatement(sql); loadParameters(statement, params, row); rs = statement.executeQuery(); rs.next(); return rs.getInt(1); } finally { if (rs != null) { try { rs.close(); } catch (SQLException sqle) { } } if (statement != null) { try { statement.close(); } catch (SQLException sqle) { } } } }