Add method to load properties for arbitrary objects.
[demoscenemusic.git] / src / main / java / net / pterodactylus / demoscenemusic / data / DataManager.java
index 42952f9..5324d28 100644 (file)
@@ -24,6 +24,7 @@ import java.util.EnumMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 import java.util.UUID;
 import java.util.concurrent.Callable;
 
@@ -63,6 +64,10 @@ public class DataManager {
        @SuppressWarnings("synthetic-access")
        private final ObjectCreator<Track> trackCreator = new TrackCreator();
 
+       /** The track object creator. */
+       @SuppressWarnings("synthetic-access")
+       private final ObjectCreator<TrackDerivative> trackDerivativeCreator = new TrackDerivativeCreator();
+
        /** The style object creator. */
        @SuppressWarnings("synthetic-access")
        private final ObjectCreator<Style> styleCreator = new StyleCreator();
@@ -94,7 +99,7 @@ public class DataManager {
        public Collection<Artist> getAllArtists() throws DatabaseException {
                Query query = new Query(Type.SELECT, "ARTISTS");
                query.addField(new Field("ARTISTS.*"));
-               return database.getMultiple(query, artistCreator);
+               return loadProperties(database.getMultiple(query, artistCreator));
        }
 
        /**
@@ -111,7 +116,7 @@ public class DataManager {
                Query query = new Query(Type.SELECT, "ARTISTS");
                query.addField(new Field("ARTISTS.*"));
                query.addWhereClause(new ValueFieldWhereClause(new ValueField("ARTISTS.ID", new StringParameter(id))));
-               return database.getSingle(query, artistCreator);
+               return loadProperties(database.getSingle(query, artistCreator));
        }
 
        /**
@@ -128,7 +133,7 @@ public class DataManager {
                query.addField(new Field("ARTISTS.*"));
                query.addJoin(new Join(JoinType.INNER, "GROUP_ARTISTS", new Field("ARTISTS.ID"), new Field("GROUP_ARTISTS.ARTIST")));
                query.addWhereClause(new ValueFieldWhereClause(new ValueField("GROUP_ARTISTS.GROUP_", new StringParameter(groupId))));
-               return database.getMultiple(query, artistCreator);
+               return loadProperties(database.getMultiple(query, artistCreator));
        }
 
        /**
@@ -146,7 +151,7 @@ public class DataManager {
                query.addJoin(new Join(JoinType.INNER, "TRACK_ARTISTS", new Field("TRACK_ARTISTS.ARTIST"), new Field("ARTISTS.ID")));
                query.addWhereClause(new ValueFieldWhereClause(new ValueField("TRACK_ARTISTS.TRACK", new StringParameter(trackId))));
                query.addOrderField(new OrderField(new Field("TRACK_ARTISTS.DISPLAY_ORDER")));
-               return database.getMultiple(query, artistCreator);
+               return loadProperties(database.getMultiple(query, artistCreator));
        }
 
        /**
@@ -164,7 +169,7 @@ public class DataManager {
                query.addValueField(new ValueField("ID", new StringParameter(id)));
                query.addValueField(new ValueField("NAME", new StringParameter(name)));
                database.insert(query);
-               return getArtistById(id);
+               return loadProperties(getArtistById(id));
        }
 
        /**
@@ -180,6 +185,94 @@ public class DataManager {
                query.addValueField(new ValueField("NAME", new StringParameter(artist.getName())));
                query.addWhereClause(new ValueFieldWhereClause(new ValueField("ID", new StringParameter(artist.getId()))));
                database.update(query);
+               saveArtistProperties(artist);
+       }
+
+       /**
+        * Saves the properties of the given artist.
+        *
+        * @param artist
+        *            The artist whose properties to save
+        * @throws DatabaseException
+        *             if a database error occurs
+        */
+       public void saveArtistProperties(Artist artist) throws DatabaseException {
+               saveProperties(artist.getProperties(), "ARTIST_PROPERTIES", "ARTIST", artist.getId());
+       }
+
+       /**
+        * Saves the given properties to the given table for the given principal.
+        *
+        * @param properties
+        *            The properties to save
+        * @param table
+        *            The table in which to save the properties
+        * @param type
+        *            The type of the principal (e. g. “ARTIST” or “TRACK”)
+        * @param id
+        *            The ID of the principial
+        * @throws DatabaseException
+        *             if a database error occurs
+        */
+       public void saveProperties(Properties properties, String table, String type, String id) throws DatabaseException {
+               if (!properties.isDirty()) {
+                       return;
+               }
+               Query query = new Query(Type.DELETE, table);
+               query.addWhereClause(new ValueFieldWhereClause(new ValueField(type, new StringParameter(id))));
+               database.update(query);
+               for (Entry<String, String> property : properties) {
+                       Query insertQuery = new Query(Type.INSERT, table);
+                       insertQuery.addValueField(new ValueField(type, new StringParameter(id)));
+                       insertQuery.addValueField(new ValueField("PROPERTY", new StringParameter(property.getKey())));
+                       insertQuery.addValueField(new ValueField("VALUE", new StringParameter(property.getValue())));
+                       database.insert(insertQuery);
+               }
+               properties.resetDirty();
+       }
+
+       /**
+        * Loads the properties for an artist.
+        *
+        * @param artist
+        *            The artist to load the properties for
+        * @return The artist
+        * @throws DatabaseException
+        *             if a database error occurs
+        */
+       public Artist loadProperties(final Artist artist) throws DatabaseException {
+               Query query = new Query(Type.SELECT, "ARTIST_PROPERTIES");
+               query.addField(new Field("ARTIST_PROPERTIES.PROPERTY"));
+               query.addField(new Field("ARTIST_PROPERTIES.VALUE"));
+               query.addWhereClause(new ValueFieldWhereClause(new ValueField("ARTIST", new StringParameter(artist.getId()))));
+               database.process(query, new ResultProcessor() {
+
+                       @Override
+                       public void processResult(ResultSet resultSet) throws SQLException {
+                               if (resultSet.isFirst()) {
+                                       artist.getProperties().removeAll();
+                               }
+                               artist.getProperties().set(resultSet.getString("ARTIST_PROPERTIES.PROPERTY"), resultSet.getString("ARTIST_PROPERTIES.VALUE"));
+                       }
+
+               });
+               return artist;
+       }
+
+       /**
+        * Loads the properties of all given artists.
+        *
+        * @param artists
+        *            The artists to load the properties for
+        * @return The list of artists
+        * @throws DatabaseException
+        *             if a database error occurs
+        */
+       public List<Artist> loadProperties(List<Artist> artists) throws DatabaseException {
+               for (Artist artist : artists) {
+                       loadProperties(artist);
+               }
+               return artists;
        }
 
        /**
@@ -350,6 +443,44 @@ public class DataManager {
                return database.getMultiple(query, new StringCreator("USER_OPENIDS.OPENID"));
        }
 
+       //
+       // PRIVATE METHODS
+       //
+
+       /**
+        * Loads the properties for the given object.
+        *
+        * @param <T>
+        *            The type of the object
+        * @param object
+        *            The object
+        * @param table
+        *            The table to load the properties from
+        * @param type
+        *            The type of the object (“ARTIST,” “TRACK,” etc.)
+        * @return The object with its properties loaded
+        * @throws DatabaseException
+        *             if a database error occurs
+        */
+       private <T extends Base> T loadProperties(final T object, final String table, String type) throws DatabaseException {
+               Query query = new Query(Type.SELECT, table);
+               query.addField(new Field(table + ".PROPERTY"));
+               query.addField(new Field(table + ".VALUE"));
+               query.addWhereClause(new ValueFieldWhereClause(new ValueField(type, new StringParameter(object.getId()))));
+               database.process(query, new ResultProcessor() {
+
+                       @Override
+                       public void processResult(ResultSet resultSet) throws SQLException {
+                               if (resultSet.isFirst()) {
+                                       object.getProperties().removeAll();
+                               }
+                               object.getProperties().set(resultSet.getString(table + ".PROPERTY"), resultSet.getString(table + ".VALUE"));
+                       }
+
+               });
+               return object;
+       }
+
        /**
         * {@link Artist} implementation that retrieves some attributes (such as
         * {@link #getGroups()}, and {@link #getTracks()}) from the
@@ -633,6 +764,24 @@ public class DataManager {
        }
 
        /**
+        * {@link ObjectCreator} implementation that can create
+        * {@link TrackDerivative} objects.
+        *
+        * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+        */
+       private class TrackDerivativeCreator implements ObjectCreator<TrackDerivative> {
+
+               /**
+                * {@inheritDoc}
+                */
+               @Override
+               public TrackDerivative createObject(ResultSet resultSet) throws SQLException {
+                       return new DefaultTrackDerivative(resultSet.getString("TRACK_DERIVATIVES.ID"));
+               }
+
+       }
+
+       /**
         * {@link ObjectCreator} implementation that can create {@link Style}
         * objects.
         *