#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