/**
* Copyright 2013-2016 Amazon.com,
* Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Amazon Software License (the "License").
* You may not use this file except in compliance with the
* License. A copy of the License is located at
*
* http://aws.amazon.com/asl/
*
* or in the "license" file accompanying this file. This file is
* distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, express or implied. See the License
* for the specific language governing permissions and
* limitations under the License.
*/
package com.amazonaws.mobileconnectors.cognito;
import com.amazonaws.mobileconnectors.cognito.exceptions.DataStorageException;
import java.util.List;
import java.util.Map;
/**
* Dataset is the container of {@link Record}s. It can have up to 1k
* {@link Record} or 1 MB in size. A typical use of {@link Dataset} is the
* following.
*
* <pre>
* // open or create dataset
* Dataset dataset = cognitoClient.openOrCreate("new dataset");
* // synchronize. It pulls down latest changes from remote storage
* // and push local changes to remote storage
* dataset.synchronize(syncCallback);
* // reads value
* String highScore = dataset.getValue("high_score");
* String name = dataset.getValue("name");
* // sets value
* dataset.put("high_score", "90");
* dataset.put("name", "John");
* // push changes to remote if needed
* dataset.synchronizesyncCallback);
* </pre>
*/
public interface Dataset {
/**
* Retrieves the associated {@link DatasetMetadata} from local storage.
*
* @return metadata
*/
DatasetMetadata getDatasetMetadata();
/**
* Synchronize {@link Dataset} between local storage and remote storage.
*
* @param callback call back
*/
void synchronize(SyncCallback callback);
/**
* Attempt to synchronize {@link Dataset} when connectivity is available. If
* the connectivity is available right away, it behaves the same as
* {@link #synchronize(SyncCallback)}. Otherwise it listens to connectivity
* changes, and will do a sync once the connectivity is back. Note that if
* this method is called multiple times, only the last synchronize request
* is kept and only the last callback will fire. If either the dataset or
* the callback is garbage collected, this method will not perform a sync
* and the callback won't fire.
*
* @param callback call back
*/
void synchronizeOnConnectivity(SyncCallback callback);
/**
* Gets the value of a {@link Record} with the given key. If the
* {@link Record} doesn't exist or is marked deleted, null will be returned.
*
* @param key key of the record in the dataset.
* @return the string value of the record, or null if the record doesn't
* exist or is marked deleted.
*/
String get(String key);
/**
* Puts a {@link Record} with the given key and value into the
* {@link Dataset}. If a {@link Record} with the same key exists, its value
* will be overwritten. If a {@link Record} is marked as deleted previously,
* then it will be resurrected with new value while the sync count continues
* with previous value. No matter whether the value changes or not, the
* record is considered as updated, and it will be written to Cognito Sync
* service on next synchronize operation. If value is null, a
* {@link NullPointerException} will be thrown.
*
* @param key key of the record
* @param value string value of a {@link Record} to be put into the
* {@link Dataset}
*/
void put(String key, String value);
/**
* @param values
*/
void putAll(Map<String, String> values);
/**
* Marks a {@link Record} with the given key as deleted. Nothing happens if
* the {@link Record} doesn't exist or is deleted already.
*
* @param key
*/
void remove(String key);
/**
* Saves resolved conflicting {@link Record}s into local storage. This is
* used inside {@link SyncCallback#onConflict(Dataset, List)} after you
* resolve all conflicts.
*
* @param resolvedConflicts a list of records to save into local storage
*/
void resolve(List<Record> resolvedConflicts);
/**
* Retrieves all raw records, marked deleted or not, from local storage.
*
* @return a list of all raw records
*/
List<Record> getAllRecords();
/**
* Gets the key-value representation of all records of this dataset. Marked
* as deleted records are excluded.
*
* @return key-value representation of all records, excluding deleted ones
*/
Map<String, String> getAll();
/**
* Gets the total size in bytes of this dataset. Records that are marked as
* deleted don't contribute to the total size.
*
* @return size in bytes
*/
long getTotalSizeInBytes();
/**
* Gets the size of a record with the given key. If the key is deleted, -1
* will be returned.
*
* @param key the key of a record
* @return size in bytes
*/
long getSizeInBytes(String key);
/**
* Retrieves the status of a record.
*
* @param key the key of a record
* @return True if it is modified locally. False otherwise
*/
boolean isChanged(String key);
/**
* Delete this {@link Dataset}. No more following operations on this
* dataset, or else {@link IllegalStateException} will be thrown.
*/
void delete();
/**
* Get the last sync count of this {@link Dataset}.
*
* @return last sync count
*/
long getLastSyncCount();
/**
* Subscribes the user to update notifications for a dataset. This should
* only be called after the device has been registered.
*/
void subscribe();
/**
* Unsubscribe the user from receiving notifications on updates to a dataset
* which has previously been subscribed to.
*/
void unsubscribe();
/**
* This is the callback used in {@link Dataset#synchronize(SyncCallback)}.
*/
interface SyncCallback {
/**
* This is called after remote changes are downloaded to local storage
* and local changes are uploaded to remote storage. Updated records
* from remote storage are passed in the callback. If conflicts occur
* during synchronize and are resolved in {@link #onConflict} after
* several retries, then updatedRecords will be what are pulled down
* from remote in the last retry.
*
* @param dataset the dataset that performed sync
* @param updatedRecords new records from remote storage that are
* downloaded
*/
void onSuccess(Dataset dataset, List<Record> updatedRecords);
/**
* This can be triggered during two phases. One is when the remote
* changes are about to be written to local storage. The other is when
* local changes are uploaded to remote storage and got rejected. Here
* is an example:
*
* <pre>
* List<Record> resolved = new ArrayList<Record>();
* for (SyncConflict conflict : conflicts) {
* resolved.add(conflicts.resolveWithRemoteRecord());
* }
* dataset.save(resolved);
* return true; // so that synchronize() can retry
* </pre>
*
* If you prefer to add additional logic when resolving conflict, you
* can use {@link SyncConflict#resolveWithValue(String)}
*
* <pre>
* int remoteMoney = Integer.valueOf(conflicts.getRemote().getValue());
* int localMoney = Integer.valueOf(conflicts.getLocal().getValue());
* int total = remoteMoney + localMoney;
* Record resolve = conflicts.resolveWithValue(String.valueOf(total));
* </pre>
*
* @param dataset the dataset that performed sync
* @param conflicts conflicting records
* @return true if conflicts are resolved so that synchronize will
* retry, false otherwise.
*/
boolean onConflict(Dataset dataset, List<SyncConflict> conflicts);
/**
* This is triggered when the given dataset is deleted remotely. Return
* true if you want to remove local dataset, or false if you want to
* keep it.
*
* @param dataset dataset handler
* @param datasetName the name of the dataset that is deleted remotely
* @return true to remove local dataset, or false to keep it
*/
boolean onDatasetDeleted(Dataset dataset, String datasetName);
/**
* If two or more datasets are merged as a result of identity merge,
* this will be triggered. A list of names of merged datasets' is passed
* in. The merged dataset name will be appended with its old identity
* id. One can open the merged dataset, synchronize the content,
* reconcile with the current dataset, and remove it. This callback will
* fire off until the merged dataset is removed.
*
* @param dataset dataset handler
* @param datasetNames a list of names of merged datasets'
* @return true if the merge is resolved so that synchronize will retry, false otherwise.
*/
boolean onDatasetsMerged(Dataset dataset, List<String> datasetNames);
/**
* This is called when an exception occurs during sync.
*
* @param dse exception
*/
void onFailure(DataStorageException dse);
}
}