add openhack files
This commit is contained in:
@ -0,0 +1,145 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for details.
|
||||
|
||||
using System;
|
||||
using MyDriving.DataStore.Abstractions;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.WindowsAzure.MobileServices;
|
||||
using Microsoft.WindowsAzure.MobileServices.Sync;
|
||||
using MyDriving.Utils;
|
||||
using System.Collections.Generic;
|
||||
using MyDriving.DataObjects;
|
||||
using Plugin.Connectivity;
|
||||
using MyDriving.AzureClient;
|
||||
using MyDriving.Utils.Interfaces;
|
||||
|
||||
namespace MyDriving.DataStore.Azure.Stores
|
||||
{
|
||||
public class BaseStore<T> : IBaseStore<T> where T : class, IBaseDataObject, new()
|
||||
{
|
||||
IStoreManager storeManager;
|
||||
|
||||
IMobileServiceSyncTable<T> table;
|
||||
|
||||
protected IMobileServiceSyncTable<T> Table =>
|
||||
table ?? (table = ServiceLocator.Instance.Resolve<IAzureClient>()?.Client?.GetSyncTable<T>());
|
||||
|
||||
public virtual string Identifier => "Items";
|
||||
|
||||
public virtual Task<bool> DropTable()
|
||||
{
|
||||
table = null;
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
#region IBaseStore implementation
|
||||
|
||||
public virtual async Task<bool> RemoveItemsAsync(IEnumerable<T> items)
|
||||
{
|
||||
bool result = true;
|
||||
foreach (var item in items)
|
||||
{
|
||||
result = result && await RemoveAsync(item);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task InitializeStoreAsync()
|
||||
{
|
||||
if (storeManager == null)
|
||||
storeManager = ServiceLocator.Instance.Resolve<IStoreManager>();
|
||||
|
||||
if (!storeManager.IsInitialized)
|
||||
await storeManager.InitializeAsync();
|
||||
}
|
||||
|
||||
public virtual async Task<IEnumerable<T>> GetItemsAsync(int skip = 0, int take = 100, bool forceRefresh = false)
|
||||
{
|
||||
await InitializeStoreAsync();
|
||||
if (forceRefresh)
|
||||
{
|
||||
await SyncAsync();
|
||||
}
|
||||
|
||||
return await Table.ToEnumerableAsync();
|
||||
}
|
||||
|
||||
public virtual async Task<T> GetItemAsync(string id)
|
||||
{
|
||||
await InitializeStoreAsync();
|
||||
await SyncAsync();
|
||||
var item = await Table.LookupAsync(id);
|
||||
return item;
|
||||
}
|
||||
|
||||
public virtual async Task<bool> InsertAsync(T item)
|
||||
{
|
||||
await InitializeStoreAsync();
|
||||
await Table.InsertAsync(item); //Insert into the local store
|
||||
await SyncAsync(); //Send changes to the mobile service
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual async Task<bool> UpdateAsync(T item)
|
||||
{
|
||||
await InitializeStoreAsync();
|
||||
await Table.UpdateAsync(item); //Delete from the local store
|
||||
await SyncAsync(); //Send changes to the mobile service
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual async Task<bool> RemoveAsync(T item)
|
||||
{
|
||||
bool result = false;
|
||||
try
|
||||
{
|
||||
await InitializeStoreAsync();
|
||||
await Table.DeleteAsync(item); //Delete from the local store
|
||||
await SyncAsync(); //Send changes to the mobile service
|
||||
result = true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Instance.Track($"Unable to remove item {item.Id}:{e}");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//Note: do not call SyncAsync with ConfigureAwait(false) because when the authentication token expires,
|
||||
//the thread running this method needs to open the Login UI.
|
||||
//Also in the method which calls SyncAsync, do not use ConfigureAwait(false) before calling SyncAsync, because once ConfigureAwait(false) is used
|
||||
//in the context of an async method, the rest of that method's code may also run on a background thread.
|
||||
public virtual async Task<bool> SyncAsync()
|
||||
{
|
||||
if (!CrossConnectivity.Current.IsConnected)
|
||||
{
|
||||
Logger.Instance.Track("Unable to sync items, we are offline");
|
||||
return false;
|
||||
}
|
||||
try
|
||||
{
|
||||
var client = ServiceLocator.Instance.Resolve<IAzureClient>()?.Client;
|
||||
if (client == null)
|
||||
{
|
||||
Logger.Instance.Track("Unable to sync items, client is null");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//push changes on the sync context before pulling new items
|
||||
await client.SyncContext.PushAsync();
|
||||
await Table.PullAsync($"all{Identifier}", Table.CreateQuery());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Instance.Track("SyncAsync: Unable to push/pull items: " + ex.Message);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for details.
|
||||
|
||||
using MyDriving.DataObjects;
|
||||
using MyDriving.DataStore.Abstractions;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MyDriving.DataStore.Azure.Stores
|
||||
{
|
||||
public class IOTHubStore : BaseStore<IOTHubData>, IHubIOTStore
|
||||
{
|
||||
public override string Identifier => "IOTHub";
|
||||
|
||||
public override Task<bool> SyncAsync()
|
||||
{
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
object locker = new object();
|
||||
public override Task<bool> InsertAsync(IOTHubData item)
|
||||
{
|
||||
lock(locker)
|
||||
{
|
||||
return base.InsertAsync(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for details.
|
||||
|
||||
using MyDriving.DataObjects;
|
||||
using MyDriving.DataStore.Abstractions;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using System.Linq;
|
||||
|
||||
namespace MyDriving.DataStore.Azure.Stores
|
||||
{
|
||||
public class POIStore : BaseStore<POI>, IPOIStore
|
||||
{
|
||||
public async Task<IEnumerable<POI>> GetItemsAsync(string tripId)
|
||||
{
|
||||
//Always force refresh
|
||||
await InitializeStoreAsync();
|
||||
await SyncAsync();
|
||||
return await Table.CreateQuery().Where(p => p.TripId == tripId).ToEnumerableAsync();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for details.
|
||||
|
||||
using MyDriving.DataObjects;
|
||||
using MyDriving.DataStore.Abstractions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MyDriving.DataStore.Azure.Stores
|
||||
{
|
||||
public class PhotoStore : BaseStore<Photo>, IPhotoStore
|
||||
{
|
||||
public override string Identifier => "Photo";
|
||||
|
||||
public override Task<bool> SyncAsync()
|
||||
{
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
public Task<IEnumerable<Photo>> GetTripPhotos(string tripId)
|
||||
{
|
||||
return Table.Where(s => s.TripId == tripId).ToEnumerableAsync();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
using Microsoft.WindowsAzure.MobileServices;
|
||||
using MyDriving.AzureClient;
|
||||
using MyDriving.DataObjects;
|
||||
using MyDriving.DataStore.Abstractions;
|
||||
using MyDriving.Utils;
|
||||
using Plugin.Connectivity;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MyDriving.DataStore.Azure.Stores
|
||||
{
|
||||
public class TripPointStore : BaseStore<TripPoint>, ITripPointStore
|
||||
{
|
||||
public override string Identifier => "TripPoint";
|
||||
|
||||
public override async Task<bool> InsertAsync(TripPoint item)
|
||||
{
|
||||
await Table.InsertAsync(item);
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<TripPoint>> GetPointsForTripAsync(string id)
|
||||
{
|
||||
await InitializeStoreAsync();
|
||||
|
||||
//first look locally for points.
|
||||
var points = await Table.Where(s => s.TripId == id).OrderBy(p => p.Sequence).ToEnumerableAsync();
|
||||
|
||||
if (points.Any())
|
||||
return points;
|
||||
|
||||
|
||||
if (!CrossConnectivity.Current.IsConnected)
|
||||
{
|
||||
Logger.Instance.Track("Unable to pull items, we are offline");
|
||||
return new List<TripPoint>();
|
||||
}
|
||||
|
||||
//if we don't have any points then we need to go up and pull them down.
|
||||
try
|
||||
{
|
||||
//await SyncAsync();
|
||||
var pullId = $"{id}";
|
||||
await Table.PullAsync(pullId, Table.Where(s => s.TripId == id));
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Instance.Track("TripPointStore: Unable to pull items: " + ex.Message);
|
||||
}
|
||||
|
||||
return await Table.Where(s => s.TripId == id).OrderBy(p => p.Sequence).ToEnumerableAsync();
|
||||
}
|
||||
|
||||
public override async Task<bool> SyncAsync()
|
||||
{
|
||||
if (!CrossConnectivity.Current.IsConnected)
|
||||
{
|
||||
Logger.Instance.Track("Unable to sync items, we are offline");
|
||||
return false;
|
||||
}
|
||||
try
|
||||
{
|
||||
var client = ServiceLocator.Instance.Resolve<IAzureClient>()?.Client;
|
||||
await client.SyncContext.PushAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Instance.Track("TripPointStore SyncAsync: Unable to sync items: " + ex.Message);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,105 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for details.
|
||||
|
||||
using System;
|
||||
using MyDriving.DataObjects;
|
||||
using MyDriving.DataStore.Abstractions;
|
||||
using System.Threading.Tasks;
|
||||
using MyDriving.Utils;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using MyDriving.AzureClient;
|
||||
|
||||
namespace MyDriving.DataStore.Azure.Stores
|
||||
{
|
||||
public class TripStore : BaseStore<Trip>, ITripStore
|
||||
{
|
||||
readonly IPhotoStore photoStore;
|
||||
readonly ITripPointStore pointStore;
|
||||
public TripStore()
|
||||
{
|
||||
photoStore = ServiceLocator.Instance.Resolve<IPhotoStore>();
|
||||
pointStore = ServiceLocator.Instance.Resolve<ITripPointStore>();
|
||||
}
|
||||
|
||||
public override string Identifier => "Trip";
|
||||
|
||||
public override async Task<bool> InsertAsync(Trip item)
|
||||
{
|
||||
return await base.InsertAsync(item);
|
||||
}
|
||||
|
||||
public override async Task<IEnumerable<Trip>> GetItemsAsync(int skip = 0, int take = 100,
|
||||
bool forceRefresh = false)
|
||||
{
|
||||
await InitializeStoreAsync();
|
||||
if (forceRefresh)
|
||||
{
|
||||
await SyncAsync();
|
||||
}
|
||||
|
||||
var items = await Table.Skip(skip).Take(take).OrderByDescending(s => s.RecordedTimeStamp).ToEnumerableAsync();
|
||||
|
||||
foreach (var item in items)
|
||||
{
|
||||
item.Photos = new List<Photo>();
|
||||
var photos = await photoStore.GetTripPhotos(item.Id);
|
||||
foreach (var photo in photos)
|
||||
item.Photos.Add(photo);
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
public override async Task<Trip> GetItemAsync(string id)
|
||||
{
|
||||
var item = await base.GetItemAsync(id);
|
||||
|
||||
if (item.Photos == null)
|
||||
item.Photos = new List<Photo>();
|
||||
else
|
||||
item.Photos.Clear();
|
||||
|
||||
var photos = await photoStore.GetTripPhotos(item.Id);
|
||||
foreach (var photo in photos)
|
||||
item.Photos.Add(photo);
|
||||
|
||||
|
||||
item.Points = item.Points.OrderBy(p => p.Sequence).ToArray();
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public override async Task<bool> RemoveAsync(Trip item)
|
||||
{
|
||||
bool result = false;
|
||||
try
|
||||
{
|
||||
await InitializeStoreAsync();
|
||||
|
||||
var t = ServiceLocator.Instance.Resolve<IAzureClient>()?.Client?.GetSyncTable<TripPoint>();
|
||||
|
||||
var points = item.Points;
|
||||
if (points == null || points.Count == 0)
|
||||
{
|
||||
points = new List<TripPoint>(await pointStore.GetPointsForTripAsync(item.Id));
|
||||
}
|
||||
|
||||
foreach (var point in points)
|
||||
{
|
||||
await t.DeleteAsync(point);
|
||||
}
|
||||
|
||||
await Table.DeleteAsync(item); //Delete from the local store
|
||||
await SyncAsync(); //Send changes to the mobile service
|
||||
result = true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Instance.Track($"Unable to remove item {item.Id}:{e}");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for details.
|
||||
|
||||
using MyDriving.DataObjects;
|
||||
using MyDriving.DataStore.Abstractions;
|
||||
using System.Linq;
|
||||
|
||||
namespace MyDriving.DataStore.Azure.Stores
|
||||
{
|
||||
public class UserStore : BaseStore<UserProfile>, IUserStore
|
||||
{
|
||||
public override string Identifier => "User";
|
||||
|
||||
public override async System.Threading.Tasks.Task<UserProfile> GetItemAsync(string id)
|
||||
{
|
||||
var users = await base.GetItemsAsync(0, 10, true);
|
||||
return users.FirstOrDefault(s => s.UserId == id);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user