package edu.washington.geopost; import java.io.ByteArrayOutputStream; import android.graphics.Bitmap; import android.util.Log; import com.google.android.gms.maps.model.LatLng; import com.parse.ParseException; import com.parse.ParseFile; import com.parse.ParseGeoPoint; import com.parse.ParseQuery; import com.parse.ParseRelation; import com.parse.ParseUser; /** * DBStore sends information to the Parse database using parameterized queries. * * @authors Neil Hinnant, Andrew Repp */ public class DBStore { /** * Creates and adds a new pin to the pin database * @param coord The new pin's coordinates. Must not be null * @param message The new pin's message. Must not be null * @param photo The new pin's photo. Null if the pin doesn't have a photo * @return The created pin, or null if updating the database failed or the * coordinates or message is null */ public Pin postPin(LatLng coord, String message, Bitmap photo) { // Check the message and coordinates are valid if (message == null || coord == null) { return null; } // Make the ParsePin to save to the database and set its fields ParsePin dbPin = new ParsePin(); ParseUser user = ParseUser.getCurrentUser(); dbPin.setUser(user); ParseGeoPoint location = new ParseGeoPoint(coord.latitude, coord.longitude); dbPin.setLocation(location); dbPin.setMessage(message); // Check if we have a photo. If we do, try to save it to the database // and update the pin to have this photo. Log.d("PostPin", "Before photo"); if (photo != null) { Log.d("PHOTO", "before scaling"); ByteArrayOutputStream bos = new ByteArrayOutputStream(); photo.compress(Bitmap.CompressFormat.JPEG, 100, bos); byte[] scaledPhoto = bos.toByteArray(); Log.d("PHOTO", "after scaling"); ParseFile photoFile = new ParseFile("pinPhoto.jpg", scaledPhoto); try { photoFile.save(); Log.d("PostPin", "Successfully finished photo save"); dbPin.setPhoto(photoFile); } catch (ParseException e) { // Error saving photo Log.d("PostPin", "ParseException with ParseFile.save()"); return null; } } Log.d("PostPin", "After photo"); // Attempt to save the pin to the database. If there's an error, return // null. try { dbPin.save(); } catch (ParseException e) { // Error saving pin Log.d("PostPin", "ParseException with ParseObject.save()"); return null; } // Update the user's viewed and posted pins to contain the new pin ParseRelation<ParsePin> viewedPins = user.getRelation("viewed"); viewedPins.add(dbPin); ParseRelation<ParsePin> postedPins = user.getRelation("posted"); postedPins.add(dbPin); user.saveEventually(); Pin newPin = new Pin(false, coord, user.getUsername(), user.getString("facebookID"), dbPin.getObjectId(), message, photo); return newPin; } /** * Marks the given pin as being unlocked by the given user and saves the * information to the database. * @param pin The pin that the user is trying to unlock * @return A copy of the Pin marked as unlocked if successful, null * otherwise */ public Pin unlockPin(Pin pin) { // Get the ParsePin corresponding to the given Pin. ParseQuery<ParsePin> query = ParseQuery.getQuery(ParsePin.class); ParsePin dbPin = null; try { dbPin = query.get(pin.getPinId()); } catch (Exception e) { // Error fetching pin Log.d("unlockPin", "exception"); return null; } // Because we successfully got the ParsePin, get the current user, add // the ParsePin to that user's set of viewed pins, and save the updated // state to the database. ParseUser user = ParseUser.getCurrentUser(); ParseRelation<ParsePin> viewedPins = user.getRelation("viewed"); viewedPins.add(dbPin); user.saveEventually(); return createUnlockedPin(pin); } /** * Returns an unlocked version of the given Pin. * @param p The pin to copy * @return A copy of p marked as unlocked */ private Pin createUnlockedPin(Pin p) { return new Pin(false, p.getLocation(), p.getUser(), p.getFacebookID(), p.getPinId(), p.getMessage(), p.getPhoto()); } }