Google Api
This commit is contained in:
parent
e307811d89
commit
83f9fc1bd8
123 changed files with 12961 additions and 60 deletions
183
Yavsc/GoogleApiSupport/Google.Apis/Util/Store/FileDataStore.cs
Normal file
183
Yavsc/GoogleApiSupport/Google.Apis/Util/Store/FileDataStore.cs
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
/*
|
||||
Copyright 2017 Google Inc
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// TODO: This does not support UWP Storage.
|
||||
|
||||
using Google.Apis.Json;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Google.Apis.Util.Store
|
||||
{
|
||||
/// <summary>
|
||||
/// File data store that implements <see cref="IDataStore"/>. This store creates a different file for each
|
||||
/// combination of type and key. This file data store stores a JSON format of the specified object.
|
||||
/// </summary>
|
||||
public class FileDataStore : IDataStore
|
||||
{
|
||||
private const string XdgDataHomeSubdirectory = "google-filedatastore";
|
||||
private static readonly Task CompletedTask = Task.FromResult(0);
|
||||
|
||||
readonly string folderPath;
|
||||
/// <summary>Gets the full folder path.</summary>
|
||||
public string FolderPath { get { return folderPath; } }
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new file data store. If <c>fullPath</c> is <c>false</c> the path will be used as relative to
|
||||
/// <c>Environment.SpecialFolder.ApplicationData"</c> on Windows, or <c>$HOME</c> on Linux and MacOS,
|
||||
/// otherwise the input folder will be treated as absolute.
|
||||
/// The folder is created if it doesn't exist yet.
|
||||
/// </summary>
|
||||
/// <param name="folder">Folder path.</param>
|
||||
/// <param name="fullPath">
|
||||
/// Defines whether the folder parameter is absolute or relative to
|
||||
/// <c>Environment.SpecialFolder.ApplicationData</c> on Windows, or<c>$HOME</c> on Linux and MacOS.
|
||||
/// </param>
|
||||
public FileDataStore(string folder, bool fullPath = false)
|
||||
{
|
||||
folderPath = fullPath
|
||||
? folder
|
||||
: Path.Combine(GetHomeDirectory(), folder);
|
||||
if (!Directory.Exists(folderPath))
|
||||
{
|
||||
Directory.CreateDirectory(folderPath);
|
||||
}
|
||||
}
|
||||
|
||||
private string GetHomeDirectory()
|
||||
{
|
||||
string appData = Environment.GetEnvironmentVariable("APPDATA");
|
||||
if (!string.IsNullOrEmpty(appData))
|
||||
{
|
||||
// This is almost certainly windows.
|
||||
// This path must be the same between the desktop FileDataStore and this netstandard FileDataStore.
|
||||
return appData;
|
||||
}
|
||||
string home = Environment.GetEnvironmentVariable("HOME");
|
||||
if (!string.IsNullOrEmpty(home))
|
||||
{
|
||||
// This is almost certainly Linux or MacOS.
|
||||
// Follow the XDG Base Directory Specification: https://specifications.freedesktop.org/basedir-spec/latest/index.html
|
||||
// Store data in subdirectory of $XDG_DATA_HOME if it exists, defaulting to $HOME/.local/share if not set.
|
||||
string xdgDataHome = Environment.GetEnvironmentVariable("XDG_DATA_HOME");
|
||||
if (string.IsNullOrEmpty(xdgDataHome))
|
||||
{
|
||||
xdgDataHome = Path.Combine(home, ".local", "share");
|
||||
}
|
||||
return Path.Combine(xdgDataHome, XdgDataHomeSubdirectory);
|
||||
}
|
||||
throw new PlatformNotSupportedException("Relative FileDataStore paths not supported on this platform.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stores the given value for the given key. It creates a new file (named <see cref="GenerateStoredKey"/>) in
|
||||
/// <see cref="FolderPath"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type to store in the data store.</typeparam>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <param name="value">The value to store in the data store.</param>
|
||||
public Task StoreAsync<T>(string key, T value)
|
||||
{
|
||||
if (string.IsNullOrEmpty(key))
|
||||
{
|
||||
throw new ArgumentException("Key MUST have a value");
|
||||
}
|
||||
|
||||
var serialized = NewtonsoftJsonSerializer.Instance.Serialize(value);
|
||||
var filePath = Path.Combine(folderPath, GenerateStoredKey(key, typeof(T)));
|
||||
File.WriteAllText(filePath, serialized);
|
||||
return CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes the given key. It deletes the <see cref="GenerateStoredKey"/> named file in
|
||||
/// <see cref="FolderPath"/>.
|
||||
/// </summary>
|
||||
/// <param name="key">The key to delete from the data store.</param>
|
||||
public Task DeleteAsync<T>(string key)
|
||||
{
|
||||
if (string.IsNullOrEmpty(key))
|
||||
{
|
||||
throw new ArgumentException("Key MUST have a value");
|
||||
}
|
||||
|
||||
var filePath = Path.Combine(folderPath, GenerateStoredKey(key, typeof(T)));
|
||||
if (File.Exists(filePath))
|
||||
{
|
||||
File.Delete(filePath);
|
||||
}
|
||||
return CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the stored value for the given key or <c>null</c> if the matching file (<see cref="GenerateStoredKey"/>
|
||||
/// in <see cref="FolderPath"/> doesn't exist.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type to retrieve.</typeparam>
|
||||
/// <param name="key">The key to retrieve from the data store.</param>
|
||||
/// <returns>The stored object.</returns>
|
||||
public Task<T> GetAsync<T>(string key)
|
||||
{
|
||||
if (string.IsNullOrEmpty(key))
|
||||
{
|
||||
throw new ArgumentException("Key MUST have a value");
|
||||
}
|
||||
|
||||
TaskCompletionSource<T> tcs = new TaskCompletionSource<T>();
|
||||
var filePath = Path.Combine(folderPath, GenerateStoredKey(key, typeof(T)));
|
||||
if (File.Exists(filePath))
|
||||
{
|
||||
try
|
||||
{
|
||||
var obj = File.ReadAllText(filePath);
|
||||
tcs.SetResult(NewtonsoftJsonSerializer.Instance.Deserialize<T>(obj));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
tcs.SetException(ex);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tcs.SetResult(default(T));
|
||||
}
|
||||
return tcs.Task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears all values in the data store. This method deletes all files in <see cref="FolderPath"/>.
|
||||
/// </summary>
|
||||
public Task ClearAsync()
|
||||
{
|
||||
if (Directory.Exists(folderPath))
|
||||
{
|
||||
Directory.Delete(folderPath, true);
|
||||
Directory.CreateDirectory(folderPath);
|
||||
}
|
||||
|
||||
return CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary>Creates a unique stored key based on the key and the class type.</summary>
|
||||
/// <param name="key">The object key.</param>
|
||||
/// <param name="t">The type to store or retrieve.</param>
|
||||
public static string GenerateStoredKey(string key, Type t)
|
||||
{
|
||||
return string.Format("{0}-{1}", t.FullName, key);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue