diff --git a/metacat-common-server/src/main/java/com/netflix/metacat/common/server/usermetadata/LookupService.java b/metacat-common-server/src/main/java/com/netflix/metacat/common/server/usermetadata/LookupService.java index d1e31ac36..f07c62c54 100644 --- a/metacat-common-server/src/main/java/com/netflix/metacat/common/server/usermetadata/LookupService.java +++ b/metacat-common-server/src/main/java/com/netflix/metacat/common/server/usermetadata/LookupService.java @@ -31,12 +31,14 @@ public interface LookupService { /** * Returns the lookup for the given name. + * If includeValues = true, we will set the Lookup values with the associated name, otherwise empty set * * @param name lookup name + * @param includeValues whether we should set the values or not in the Lookup Object * @return lookup */ @Nullable - default Lookup get(final String name) { + default Lookup get(final String name, final boolean includeValues) { return null; } @@ -78,7 +80,7 @@ default Set getValues(final Long lookupId) { * @return updated lookup */ @Nullable - default Lookup setValues(final String name, final Set values) { + default Lookup setValues(final String name, final Set values, final boolean includeValues) { return null; } @@ -87,10 +89,11 @@ default Lookup setValues(final String name, final Set values) { * * @param name lookup name * @param values multiple values + * @param includeValues whether to include values in the final Lookup Object * @return updated lookup */ @Nullable - default Lookup addValues(final String name, final Set values) { + default Lookup addValues(final String name, final Set values, boolean includeValues) { return null; } @@ -99,10 +102,11 @@ default Lookup addValues(final String name, final Set values) { * * @param name lookup name * @param value lookup value + * @param includeValues whether to return lookup value in the Lookup Object * @return updated lookup */ @Nullable - default Lookup setValue(final String name, final String value) { + default Lookup setValue(final String name, final String value, final boolean includeValues) { return null; } diff --git a/metacat-metadata-mysql/src/main/java/com/netflix/metacat/metadata/mysql/MySqlLookupService.java b/metacat-metadata-mysql/src/main/java/com/netflix/metacat/metadata/mysql/MySqlLookupService.java index ca84d53e3..e847c380c 100644 --- a/metacat-metadata-mysql/src/main/java/com/netflix/metacat/metadata/mysql/MySqlLookupService.java +++ b/metacat-metadata-mysql/src/main/java/com/netflix/metacat/metadata/mysql/MySqlLookupService.java @@ -32,6 +32,7 @@ import java.sql.SQLException; import java.sql.Statement; import java.sql.Types; +import java.util.Collections; import java.util.Set; import java.util.stream.Collectors; @@ -50,8 +51,15 @@ public class MySqlLookupService implements LookupService { + " values (?,0,?,?,?,now(),now())"; private static final String SQL_INSERT_LOOKUP_VALUES = "insert into lookup_values( lookup_id, values_string) values (?,?)"; + private static final String SQL_INSERT_LOOKUP_VALUE_IF_NOT_EXIST = + "INSERT INTO lookup_values(lookup_id, values_string) VALUES (?,?) " + + "ON DUPLICATE KEY UPDATE lookup_id=lookup_id, values_string=values_string"; private static final String SQL_DELETE_LOOKUP_VALUES = "delete from lookup_values where lookup_id=? and values_string in (%s)"; + + private static final String SQL_DELETE_LOOKUP_VALUES_NOT_IN = + "delete from lookup_values where lookup_id=? and values_string not in (%s)"; + private static final String SQL_GET_LOOKUP_VALUES = "select values_string value from lookup_values where lookup_id=?"; private static final String SQL_GET_LOOKUP_VALUES_BY_NAME = @@ -79,7 +87,7 @@ public MySqlLookupService(final Config config, final JdbcTemplate jdbcTemplate) */ @Override @Transactional(readOnly = true) - public Lookup get(final String name) { + public Lookup get(final String name, final boolean includeValues) { try { return jdbcTemplate.queryForObject( SQL_GET_LOOKUP, @@ -93,7 +101,7 @@ public Lookup get(final String name) { lookup.setLastUpdated(rs.getDate("lastUpdated")); lookup.setLastUpdatedBy(rs.getString("lastUpdatedBy")); lookup.setDateCreated(rs.getDate("dateCreated")); - lookup.setValues(getValues(rs.getLong("id"))); + lookup.setValues(includeValues ? getValues(rs.getLong("id")) : Collections.EMPTY_SET); return lookup; }); } catch (EmptyResultDataAccessException e) { @@ -170,25 +178,13 @@ public Set getValues(final String name) { * @return returns the lookup with the given name. */ @Override - public Lookup setValues(final String name, final Set values) { + @Transactional + public Lookup setValues(final String name, final Set values, final boolean includeValues) { try { - final Lookup lookup = findOrCreateLookupByName(name); - final Set inserts; - Set deletes = Sets.newHashSet(); - final Set lookupValues = lookup.getValues(); - if (lookupValues == null || lookupValues.isEmpty()) { - inserts = values; - } else { - inserts = Sets.difference(values, lookupValues).immutableCopy(); - deletes = Sets.difference(lookupValues, values).immutableCopy(); - } + final Lookup lookup = findOrCreateLookupByName(name, includeValues); + insertLookupValuesIfNotExist(lookup.getId(), values); + deleteLookupValuesIfNotIn(lookup.getId(), values); lookup.setValues(values); - if (!inserts.isEmpty()) { - insertLookupValues(lookup.getId(), inserts); - } - if (!deletes.isEmpty()) { - deleteLookupValues(lookup.getId(), deletes); - } return lookup; } catch (Exception e) { final String message = String.format("Failed to set the lookup values for name %s", name); @@ -202,21 +198,35 @@ private void insertLookupValues(final Long id, final Set inserts) { .collect(Collectors.toList()), new int[]{Types.BIGINT, Types.VARCHAR}); } + private void insertLookupValuesIfNotExist(final Long id, final Set inserts) { + jdbcTemplate.batchUpdate(SQL_INSERT_LOOKUP_VALUE_IF_NOT_EXIST, + inserts.stream().map(insert -> new Object[]{id, insert}) + .collect(Collectors.toList()), new int[]{Types.BIGINT, Types.VARCHAR}); + } + private void deleteLookupValues(final Long id, final Set deletes) { jdbcTemplate.update( String.format(SQL_DELETE_LOOKUP_VALUES, "'" + Joiner.on("','").skipNulls().join(deletes) + "'"), new SqlParameterValue(Types.BIGINT, id)); } + private void deleteLookupValuesIfNotIn(final long id, final Set valuesToKeep) { + jdbcTemplate.update( + String.format(SQL_DELETE_LOOKUP_VALUES_NOT_IN, + "'" + Joiner.on("','").skipNulls().join(valuesToKeep) + "'"), + new SqlParameterValue(Types.BIGINT, id)); + } + /** * findOrCreateLookupByName. * * @param name name to find or create + * @param includeValues whether to include the values in the Lookup Object * @return Look up object * @throws SQLException sql exception */ - private Lookup findOrCreateLookupByName(final String name) throws SQLException { - Lookup lookup = get(name); + private Lookup findOrCreateLookupByName(final String name, final boolean includeValues) throws SQLException { + Lookup lookup = get(name, includeValues); if (lookup == null) { final KeyHolder holder = new GeneratedKeyHolder(); jdbcTemplate.update(connection -> { @@ -244,20 +254,14 @@ private Lookup findOrCreateLookupByName(final String name) throws SQLException { * @return returns the lookup with the given name. */ @Override - public Lookup addValues(final String name, final Set values) { + public Lookup addValues(final String name, final Set values, final boolean includeValues) { try { - final Lookup lookup = findOrCreateLookupByName(name); - - final Set inserts; - final Set lookupValues = lookup.getValues(); - if (lookupValues == null || lookupValues.isEmpty()) { - inserts = values; - lookup.setValues(values); - } else { - inserts = Sets.difference(values, lookupValues); + final Lookup lookup = findOrCreateLookupByName(name, includeValues); + if (!values.isEmpty()) { + insertLookupValuesIfNotExist(lookup.getId(), values); } - if (!inserts.isEmpty()) { - insertLookupValues(lookup.getId(), inserts); + if (includeValues) { + lookup.getValues().addAll(values); } return lookup; } catch (Exception e) { @@ -275,7 +279,7 @@ public Lookup addValues(final String name, final Set values) { * @return returns the lookup with the given name. */ @Override - public Lookup setValue(final String name, final String value) { - return setValues(name, Sets.newHashSet(value)); + public Lookup setValue(final String name, final String value, final boolean includeValues) { + return setValues(name, Sets.newHashSet(value), includeValues); } } diff --git a/metacat-metadata-mysql/src/main/java/com/netflix/metacat/metadata/mysql/MySqlTagService.java b/metacat-metadata-mysql/src/main/java/com/netflix/metacat/metadata/mysql/MySqlTagService.java index 8310d11ec..4064e68b3 100644 --- a/metacat-metadata-mysql/src/main/java/com/netflix/metacat/metadata/mysql/MySqlTagService.java +++ b/metacat-metadata-mysql/src/main/java/com/netflix/metacat/metadata/mysql/MySqlTagService.java @@ -126,7 +126,7 @@ public MySqlTagService( private Lookup addTags(final Set tags) { try { - return lookupService.addValues(LOOKUP_NAME_TAG, tags); + return lookupService.addValues(LOOKUP_NAME_TAG, tags, false); } catch (Exception e) { final String message = String.format("Failed adding the tags %s", tags); log.error(message, e);