Search in sources :

Example 11 with Capture

use of com.parse.boltsinternal.Capture in project Parse-SDK-Android by ParsePlatform.

the class ParsePushTest method testSendDataInBackgroundWithCallback.

@Test
public void testSendDataInBackgroundWithCallback() throws Exception {
    // Mock controller
    ParsePushController controller = mock(ParsePushController.class);
    when(controller.sendInBackground(any(ParsePush.State.class), nullable(String.class))).thenReturn(Task.<Void>forResult(null));
    ParseCorePlugins.getInstance().registerPushController(controller);
    // Make sample ParsePush data and call method
    JSONObject data = new JSONObject();
    data.put("key", "value");
    data.put("keyAgain", "valueAgain");
    ParseQuery<ParseInstallation> query = ParseInstallation.getQuery();
    query.getBuilder().whereEqualTo("foo", "bar");
    final Semaphore done = new Semaphore(0);
    final Capture<Exception> exceptionCapture = new Capture<>();
    ParsePush.sendDataInBackground(data, query, e -> {
        exceptionCapture.set(e);
        done.release();
    });
    shadowMainLooper().idle();
    // Make sure controller is executed and state parameter is correct
    assertNull(exceptionCapture.get());
    assertTrue(done.tryAcquire(1, 10, TimeUnit.SECONDS));
    ArgumentCaptor<ParsePush.State> stateCaptor = ArgumentCaptor.forClass(ParsePush.State.class);
    verify(controller, times(1)).sendInBackground(stateCaptor.capture(), nullable(String.class));
    ParsePush.State state = stateCaptor.getValue();
    // Verify query state
    ParseQuery.State<ParseInstallation> queryState = state.queryState();
    JSONObject queryStateJson = queryState.toJSON(PointerEncoder.get());
    assertEquals("bar", queryStateJson.getJSONObject("where").getString("foo"));
    // Verify data
    assertEquals(data, state.data(), JSONCompareMode.NON_EXTENSIBLE);
}
Also used : Matchers.anyString(org.mockito.Matchers.anyString) Semaphore(java.util.concurrent.Semaphore) Capture(com.parse.boltsinternal.Capture) JSONObject(org.json.JSONObject) Test(org.junit.Test)

Example 12 with Capture

use of com.parse.boltsinternal.Capture in project Parse-SDK-Android by ParsePlatform.

the class ParseObject method deepSaveAsync.

/**
 * This saves all of the objects and files reachable from the given object. It does its work in
 * multiple waves, saving as many as possible in each wave. If there's ever an error, it just
 * gives up, sets error, and returns NO.
 */
private static Task<Void> deepSaveAsync(final Object object, final String sessionToken) {
    Set<ParseObject> objects = new HashSet<>();
    Set<ParseFile> files = new HashSet<>();
    collectDirtyChildren(object, objects, files);
    // This has to happen separately from everything else because ParseUser.save() is
    // special-cased to work for lazy users, but new users can't be created by
    // ParseMultiCommand's regular save.
    Set<ParseUser> users = new HashSet<>();
    for (ParseObject o : objects) {
        if (o instanceof ParseUser) {
            ParseUser user = (ParseUser) o;
            if (user.isLazy()) {
                users.add((ParseUser) o);
            }
        }
    }
    objects.removeAll(users);
    // objects will need to wait for files to be complete since they may be nested children.
    final AtomicBoolean filesComplete = new AtomicBoolean(false);
    List<Task<Void>> tasks = new ArrayList<>();
    for (ParseFile file : files) {
        tasks.add(file.saveAsync(sessionToken, null, null));
    }
    Task<Void> filesTask = Task.whenAll(tasks).continueWith(task -> {
        filesComplete.set(true);
        return null;
    });
    // objects will need to wait for users to be complete since they may be nested children.
    final AtomicBoolean usersComplete = new AtomicBoolean(false);
    tasks = new ArrayList<>();
    for (final ParseUser user : users) {
        tasks.add(user.saveAsync(sessionToken));
    }
    Task<Void> usersTask = Task.whenAll(tasks).continueWith(task -> {
        usersComplete.set(true);
        return null;
    });
    final Capture<Set<ParseObject>> remaining = new Capture<>(objects);
    Task<Void> objectsTask = Task.forResult(null).continueWhile(() -> remaining.get().size() > 0, task -> {
        // Partition the objects into two sets: those that can be save
        // immediately,
        // and those that rely on other objects to be created first.
        final List<ParseObject> current = new ArrayList<>();
        final Set<ParseObject> nextBatch = new HashSet<>();
        for (ParseObject obj : remaining.get()) {
            if (obj.canBeSerialized()) {
                current.add(obj);
            } else {
                nextBatch.add(obj);
            }
        }
        remaining.set(nextBatch);
        if (current.size() == 0 && filesComplete.get() && usersComplete.get()) {
            // exception instead of an infinite loop.
            throw new RuntimeException("Unable to save a ParseObject with a relation to a cycle.");
        }
        // Package all save commands together
        if (current.size() == 0) {
            return Task.forResult(null);
        }
        return enqueueForAll(current, toAwait -> saveAllAsync(current, sessionToken, toAwait));
    });
    return Task.whenAll(Arrays.asList(filesTask, usersTask, objectsTask));
}
Also used : Task(com.parse.boltsinternal.Task) HashSet(java.util.HashSet) Set(java.util.Set) ArrayList(java.util.ArrayList) Capture(com.parse.boltsinternal.Capture) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) HashSet(java.util.HashSet)

Example 13 with Capture

use of com.parse.boltsinternal.Capture in project Parse-SDK-Android by ParsePlatform.

the class OfflineStore method deleteDataForObjectAsync.

private Task<Void> deleteDataForObjectAsync(final ParseObject object, final ParseSQLiteDatabase db) {
    final Capture<String> uuid = new Capture<>();
    // Make sure the object has a UUID.
    Task<String> uuidTask;
    synchronized (lock) {
        uuidTask = objectToUuidMap.get(object);
        if (uuidTask == null) {
            // database.
            return Task.forResult(null);
        }
    }
    uuidTask = uuidTask.onSuccessTask(task -> {
        uuid.set(task.getResult());
        return task;
    });
    // If the object was the root of a pin, unpin it.
    Task<Void> unpinTask = uuidTask.onSuccessTask(task -> {
        // Find all the roots for this object.
        String[] select = { OfflineSQLiteOpenHelper.KEY_KEY };
        String where = OfflineSQLiteOpenHelper.KEY_UUID + "=?";
        String[] args = { uuid.get() };
        return db.queryAsync(OfflineSQLiteOpenHelper.TABLE_DEPENDENCIES, select, where, args);
    }).onSuccessTask(task -> {
        // Try to unpin this object from the pin label if it's a root of
        // the ParsePin.
        Cursor cursor = task.getResult();
        List<String> uuids = new ArrayList<>();
        for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
            uuids.add(cursor.getString(0));
        }
        cursor.close();
        List<Task<Void>> tasks = new ArrayList<>();
        for (final String uuid1 : uuids) {
            Task<Void> unpinTask1 = getPointerAsync(uuid1, db).onSuccessTask(task12 -> {
                ParsePin pin = (ParsePin) task12.getResult();
                return fetchLocallyAsync(pin, db);
            }).continueWithTask(task1 -> {
                ParsePin pin = task1.getResult();
                List<ParseObject> modified = pin.getObjects();
                if (modified == null || !modified.contains(object)) {
                    return task1.makeVoid();
                }
                modified.remove(object);
                if (modified.size() == 0) {
                    return unpinAsync(uuid1, db);
                }
                pin.setObjects(modified);
                return saveLocallyAsync(pin, true, db);
            });
            tasks.add(unpinTask1);
        }
        return Task.whenAll(tasks);
    });
    // Delete the object from the Local Datastore in case it wasn't the root of a pin.
    return unpinTask.onSuccessTask(task -> {
        String where = OfflineSQLiteOpenHelper.KEY_UUID + "=?";
        String[] args = { uuid.get() };
        return db.deleteAsync(OfflineSQLiteOpenHelper.TABLE_DEPENDENCIES, where, args);
    }).onSuccessTask(task -> {
        String where = OfflineSQLiteOpenHelper.KEY_UUID + "=?";
        String[] args = { uuid.get() };
        return db.deleteAsync(OfflineSQLiteOpenHelper.TABLE_OBJECTS, where, args);
    }).onSuccessTask(task -> {
        synchronized (lock) {
            // Clean up
            // TODO (grantland): we should probably clean up uuidToObjectMap and
            // objectToUuidMap, but
            // getting the uuid requires a task and things might get a little
            // funky...
            fetchedObjects.remove(object);
        }
        return task;
    });
}
Also used : Context(android.content.Context) Arrays(java.util.Arrays) ConstraintMatcher(com.parse.OfflineQueryLogic.ConstraintMatcher) Pair(android.util.Pair) TextUtils(android.text.TextUtils) HashMap(java.util.HashMap) UUID(java.util.UUID) ArrayList(java.util.ArrayList) SQLiteDatabase(android.database.sqlite.SQLiteDatabase) List(java.util.List) JSONException(org.json.JSONException) Capture(com.parse.boltsinternal.Capture) Continuation(com.parse.boltsinternal.Continuation) JSONObject(org.json.JSONObject) Map(java.util.Map) ContentValues(android.content.ContentValues) LinkedList(java.util.LinkedList) Task(com.parse.boltsinternal.Task) TaskCompletionSource(com.parse.boltsinternal.TaskCompletionSource) WeakHashMap(java.util.WeakHashMap) Cursor(android.database.Cursor) Task(com.parse.boltsinternal.Task) ArrayList(java.util.ArrayList) Cursor(android.database.Cursor) Capture(com.parse.boltsinternal.Capture)

Example 14 with Capture

use of com.parse.boltsinternal.Capture in project Parse-SDK-Android by ParsePlatform.

the class OfflineStore method saveLocallyAsync.

/**
 * Stores a single object in the local database. If the object is a pointer, isn't dirty, and
 * has an objectId already, it may not be saved, since it would provide no useful data.
 *
 * @param object The object to save.
 * @param db A database connection to use.
 */
private Task<Void> saveLocallyAsync(final String key, final ParseObject object, final ParseSQLiteDatabase db) {
    // If this is just a clean, unfetched pointer known to Parse, then there is nothing to save.
    if (object.getObjectId() != null && !object.isDataAvailable() && !object.hasChanges() && !object.hasOutstandingOperations()) {
        return Task.forResult(null);
    }
    final Capture<String> uuidCapture = new Capture<>();
    // Make sure we have a UUID for the object to be saved.
    return getOrCreateUUIDAsync(object, db).onSuccessTask(task -> {
        String uuid = task.getResult();
        uuidCapture.set(uuid);
        return updateDataForObjectAsync(uuid, object, db);
    }).onSuccessTask(task -> {
        final ContentValues values = new ContentValues();
        values.put(OfflineSQLiteOpenHelper.KEY_KEY, key);
        values.put(OfflineSQLiteOpenHelper.KEY_UUID, uuidCapture.get());
        return db.insertWithOnConflict(OfflineSQLiteOpenHelper.TABLE_DEPENDENCIES, values, SQLiteDatabase.CONFLICT_IGNORE);
    });
}
Also used : Context(android.content.Context) Arrays(java.util.Arrays) ConstraintMatcher(com.parse.OfflineQueryLogic.ConstraintMatcher) Pair(android.util.Pair) TextUtils(android.text.TextUtils) HashMap(java.util.HashMap) UUID(java.util.UUID) ArrayList(java.util.ArrayList) SQLiteDatabase(android.database.sqlite.SQLiteDatabase) List(java.util.List) JSONException(org.json.JSONException) Capture(com.parse.boltsinternal.Capture) Continuation(com.parse.boltsinternal.Continuation) JSONObject(org.json.JSONObject) Map(java.util.Map) ContentValues(android.content.ContentValues) LinkedList(java.util.LinkedList) Task(com.parse.boltsinternal.Task) TaskCompletionSource(com.parse.boltsinternal.TaskCompletionSource) WeakHashMap(java.util.WeakHashMap) Cursor(android.database.Cursor) ContentValues(android.content.ContentValues) Capture(com.parse.boltsinternal.Capture)

Aggregations

Capture (com.parse.boltsinternal.Capture)14 Semaphore (java.util.concurrent.Semaphore)9 Test (org.junit.Test)9 JSONObject (org.json.JSONObject)8 ArrayList (java.util.ArrayList)6 Task (com.parse.boltsinternal.Task)5 Continuation (com.parse.boltsinternal.Continuation)4 TaskCompletionSource (com.parse.boltsinternal.TaskCompletionSource)4 HashMap (java.util.HashMap)4 Map (java.util.Map)4 Matchers.anyString (org.mockito.Matchers.anyString)4 ContentValues (android.content.ContentValues)3 Context (android.content.Context)3 Cursor (android.database.Cursor)3 SQLiteDatabase (android.database.sqlite.SQLiteDatabase)3 TextUtils (android.text.TextUtils)3 Pair (android.util.Pair)3 ConstraintMatcher (com.parse.OfflineQueryLogic.ConstraintMatcher)3 Arrays (java.util.Arrays)3 LinkedList (java.util.LinkedList)3