#if BCL35 // // Copyright 2014-2015 Amazon.com, // Inc. or its affiliates. All Rights Reserved. // // SPDX-License-Identifier: Apache-2.0 // using System; using System.Collections.Generic; using Amazon.Runtime; using Amazon.CognitoSync.Model; using Amazon.Util.Internal; namespace Amazon.CognitoSync.SyncManager.Internal { /// /// Remote data storage using Cognito Sync service on which we can invoke /// actions like creating a dataset or record. /// public partial class CognitoSyncStorage { #region GetDataset private delegate List PopulateDatasetMetadataDelegate(IAmazonCognitoSync client, ListDatasetsRequest request); private PopulateDatasetMetadataDelegate DatasetMetadataPopulator = delegate (IAmazonCognitoSync client, ListDatasetsRequest request) { var datasets = new List(); string nextToken = null; do { request.NextToken = nextToken; ListDatasetsResponse response = client.ListDatasets(request); foreach (Amazon.CognitoSync.Model.Dataset dataset in response.Datasets) { datasets.Add(ModelToDatasetMetadata(dataset)); } nextToken = response.NextToken; } while (nextToken != null); return datasets; }; private static ListDatasetsRequest PrepareListDatasetsRequest() { ListDatasetsRequest request = new ListDatasetsRequest(); // a large enough number to reduce # of requests request.MaxResults = 64; return request; } /// /// Gets a list of /// /// public List ListDatasetMetadata() { return DatasetMetadataPopulator.Invoke(client, PrepareListDatasetsRequest()); } /// /// Initiates the asynchronous execution of the ListDatasetMetadata operation. /// /// /// An AsyncCallback delegate that is invoked when the operation completes. /// A user-defined state object that is passed to the callback procedure. Retrieve this object from within the callback /// procedure using the AsyncState property. /// /// An IAsyncResult that can be used to poll or wait for results, or both; this value is also needed when invoking EndBulkPublish /// operation. public IAsyncResult BeginListDatasetMetadata(AsyncCallback callback, object state) { return DatasetMetadataPopulator.BeginInvoke(client, PrepareListDatasetsRequest(), callback, state); } /// /// Finishes the asynchronous execution of the ListDatasetMetadata operation. /// /// /// The IAsyncResult returned by the call to BeginListDatasetMetadata. public List EndListDatasetMetadata(IAsyncResult asyncResult) { return DatasetMetadataPopulator.EndInvoke(asyncResult); } #endregion #region ListUpdates private ListRecordsRequest PrepareListRecordsRequest(string datasetName, long lastSyncCount) { ListRecordsRequest request = new ListRecordsRequest(); request.IdentityPoolId = identityPoolId; request.IdentityId = this.GetCurrentIdentityId(); request.DatasetName = datasetName; request.LastSyncCount = lastSyncCount; // mark it large enough to reduce # of requests request.MaxResults = 1024; return request; } private delegate DatasetUpdates PopulateUpdatesDelegate(IAmazonCognitoSync client, ListRecordsRequest request); private PopulateUpdatesDelegate UpdatesPopulator = delegate (IAmazonCognitoSync client, ListRecordsRequest request) { var records = new List(); ListRecordsResponse response; string nextToken = null; do { request.NextToken = nextToken; response = client.ListRecords(request); foreach (Amazon.CognitoSync.Model.Record remoteRecord in response.Records) { records.Add(ModelToRecord(remoteRecord)); } // update last evaluated key nextToken = response.NextToken; } while (nextToken != null); return new DatasetUpdates( request.DatasetName, records, response.DatasetSyncCount, response.SyncSessionToken, response.DatasetExists, response.DatasetDeletedAfterRequestedSyncCount, response.MergedDatasetNames ); }; /// /// Gets a list of records which have been updated since lastSyncCount /// (inclusive). If the value of a record equals null, then the record is /// deleted. If you pass 0 as lastSyncCount, the full list of records will be /// returned. /// /// A list of records which have been updated since lastSyncCount. /// Dataset name. /// Last sync count. /// public DatasetUpdates ListUpdates(string datasetName, long lastSyncCount) { return UpdatesPopulator.Invoke(client, PrepareListRecordsRequest(datasetName, lastSyncCount)); } /// /// Initiates the asynchronous execution of the ListUpdates operation. /// /// /// Dataset name. /// Last sync count. /// An AsyncCallback delegate that is invoked when the operation completes. /// A user-defined state object that is passed to the callback procedure. Retrieve this object from within the callback /// procedure using the AsyncState property. /// /// An IAsyncResult that can be used to poll or wait for results, or both; this value is also needed when invoking EndBulkPublish /// operation. public IAsyncResult BeginListUpdates(string datasetName, long lastSyncCount, AsyncCallback callback, object state) { return UpdatesPopulator.BeginInvoke(client, PrepareListRecordsRequest(datasetName, lastSyncCount), callback, state); } /// /// Finishes the asynchronous execution of the ListUpdates operation. /// /// /// The IAsyncResult returned by the call to BeginListUpdates. /// A list of records which have been updated since lastSyncCount. public DatasetUpdates EndListUpdates(IAsyncResult asyncResult) { return UpdatesPopulator.EndInvoke(asyncResult); } #endregion #region PutRecords private UpdateRecordsRequest PrepareUpdateRecordsRequest(string datasetName, List records, string syncSessionToken) { UpdateRecordsRequest request = new UpdateRecordsRequest(); request.DatasetName = datasetName; request.IdentityPoolId = identityPoolId; request.IdentityId = this.GetCurrentIdentityId(); request.SyncSessionToken = syncSessionToken; // create patches List patches = new List(); foreach (Record record in records) { patches.Add(RecordToPatch(record)); } request.RecordPatches = patches; return request; } private static List ExtractRecords(UpdateRecordsResponse response) { List updatedRecords = new List(); foreach (Amazon.CognitoSync.Model.Record remoteRecord in response.Records) { updatedRecords.Add(ModelToRecord(remoteRecord)); } return updatedRecords; } /// /// Post updates to remote storage. Each record has a sync count. If the sync /// count doesn't match what's on the remote storage, i.e. the record is /// modified by a different device, this operation throws ConflictException. /// Otherwise it returns a list of records that are updated successfully. /// /// The records. /// Dataset name. /// Records. /// Sync session token. /// /// public List PutRecords(string datasetName, List records, string syncSessionToken) { UpdateRecordsResponse response = client.UpdateRecords(PrepareUpdateRecordsRequest(datasetName, records, syncSessionToken)); return ExtractRecords(response); } /// /// Initiates the asynchronous execution of the PutRecords operation. /// /// /// Dataset name. /// Records. /// Sync session token. /// An AsyncCallback delegate that is invoked when the operation completes. /// A user-defined state object that is passed to the callback procedure. Retrieve this object from within the callback /// procedure using the AsyncState property. /// /// An IAsyncResult that can be used to poll or wait for results, or both; this value is also needed when invoking EndPutRecords /// operation. public IAsyncResult BeginPutRecords(string datasetName, List records, string syncSessionToken, AsyncCallback callback, object state) { return client.BeginUpdateRecords(PrepareUpdateRecordsRequest(datasetName, records, syncSessionToken), callback, state); } /// /// Finishes the asynchronous execution of the PutRecords operation. /// /// /// The IAsyncResult returned by the call to BeginPutRecords. public List EndPutRecords(IAsyncResult asyncResult) { try { UpdateRecordsResponse response = client.EndUpdateRecords(asyncResult); return ExtractRecords(response); } catch (Exception ex) { throw HandleException(ex, "Failed to update records in dataset"); } } #endregion #region DeleteDataset private DeleteDatasetRequest PrepareDeleteDatasetRequest(string datasetName) { DeleteDatasetRequest request = new DeleteDatasetRequest(); request.IdentityPoolId = identityPoolId; request.IdentityId = this.GetCurrentIdentityId(); request.DatasetName = datasetName; return request; } /// /// Deletes a dataset. /// /// Dataset name. /// public void DeleteDataset(string datasetName) { client.DeleteDataset(PrepareDeleteDatasetRequest(datasetName)); } /// /// Initiates the asynchronous execution of the DeleteDataset operation. /// /// /// Dataset name. /// An AsyncCallback delegate that is invoked when the operation completes. /// A user-defined state object that is passed to the callback procedure. Retrieve this object from within the callback /// procedure using the AsyncState property. /// /// An IAsyncResult that can be used to poll or wait for results, or both; this value is also needed when invoking EndDeleteDataset /// operation. public IAsyncResult BeginDeleteDataset(string datasetName, AsyncCallback callback, object state) { return client.BeginDeleteDataset(PrepareDeleteDatasetRequest(datasetName), callback, state); } /// /// Finishes the asynchronous execution of the DeleteDataset operation. /// /// /// The IAsyncResult returned by the call to BeginDeleteDataset. public void EndDeleteDataset(IAsyncResult asyncResult) { try { client.EndDeleteDataset(asyncResult); } catch (Exception ex) { throw HandleException(ex, "Failed to delete dataset"); } client.EndDeleteDataset(asyncResult); } #endregion #region GetDatasetMetadata private DescribeDatasetRequest PrepareDescribeDatasetRequest(string datasetName) { DescribeDatasetRequest request = new DescribeDatasetRequest(); request.IdentityPoolId = identityPoolId; request.IdentityId = this.GetCurrentIdentityId(); request.DatasetName = datasetName; return request; } /// /// Retrieves the metadata of a dataset. /// /// Dataset name. /// public DatasetMetadata GetDatasetMetadata(string datasetName) { return ModelToDatasetMetadata(client.DescribeDataset(PrepareDescribeDatasetRequest(datasetName)).Dataset); } /// /// Initiates the asynchronous execution of the GetDatasetMetadata operation. /// /// /// Dataset name. /// An AsyncCallback delegate that is invoked when the operation completes. /// A user-defined state object that is passed to the callback procedure. Retrieve this object from within the callback /// procedure using the AsyncState property. /// /// An IAsyncResult that can be used to poll or wait for results, or both; this value is also needed when invoking EndGetDatasetMetadata /// operation. public IAsyncResult BeginGetDatasetMetadata(string datasetName, AsyncCallback callback, object state) { return client.BeginDescribeDataset(PrepareDescribeDatasetRequest(datasetName), callback, state); } /// /// Finishes the asynchronous execution of the GetDatasetMetadata operation. /// /// /// The IAsyncResult returned by the call to BeginGetDatasetMetadata. public DatasetMetadata EndGetDatasetMetadata(IAsyncResult asyncResult) { try { return ModelToDatasetMetadata(client.EndDescribeDataset(asyncResult).Dataset); } catch (Exception ex) { throw new DataStorageException("Failed to get metadata of dataset", ex); } } #endregion } } #endif