* AVUserExtensions.cs: chore

* AVFile.cs:
* AVObject.cs:
oneRain 2019-08-29 14:14:29 +08:00
parent 8f7dcc080d
commit e6280b828d
3 changed files with 28 additions and 63 deletions

View File

@ -1,22 +0,0 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace LeanCloud.Storage.Internal
{
/// <summary>
/// So here's the deal. We have a lot of internal APIs for AVObject, AVUser, etc.
///
/// These cannot be 'internal' anymore if we are fully modularizing things out, because
/// they are no longer a part of the same library, especially as we create things like
/// Installation inside push library.
///
/// So this class contains a bunch of extension methods that can live inside another
/// namespace, which 'wrap' the intenral APIs that already exist.
/// </summary>
public static class AVUserExtensions
{
}
}

View File

@ -23,7 +23,7 @@ namespace LeanCloud {
/// await obj.SaveAsync(); /// await obj.SaveAsync();
/// </code> /// </code>
/// </example> /// </example>
public partial class AVFile : IJsonConvertible { public class AVFile : IJsonConvertible {
internal static int objectCounter = 0; internal static int objectCounter = 0;
internal static readonly object Mutex = new object(); internal static readonly object Mutex = new object();
private FileState state; private FileState state;
@ -45,7 +45,7 @@ namespace LeanCloud {
MimeType = mimeType, MimeType = mimeType,
MetaData = metaData MetaData = metaData
}; };
this.dataStream = data; dataStream = data;
lock (Mutex) { lock (Mutex) {
objectCounter++; objectCounter++;
state.counter = objectCounter; state.counter = objectCounter;
@ -132,7 +132,7 @@ namespace LeanCloud {
objectCounter++; objectCounter++;
state.counter = objectCounter; state.counter = objectCounter;
} }
this.isExternal = true; isExternal = true;
} }
/// <summary> /// <summary>
@ -187,7 +187,7 @@ namespace LeanCloud {
} }
internal AVFile(FileState filestate) { internal AVFile(FileState filestate) {
this.state = filestate; state = filestate;
} }
internal AVFile(string objectId) internal AVFile(string objectId)
: this(new FileState() { : this(new FileState() {
@ -258,7 +258,7 @@ namespace LeanCloud {
#endregion #endregion
IDictionary<string, object> IJsonConvertible.ToJSON() { IDictionary<string, object> IJsonConvertible.ToJSON() {
if (this.IsDirty) { if (IsDirty) {
throw new InvalidOperationException( throw new InvalidOperationException(
"AVFile must be saved before it can be serialized."); "AVFile must be saved before it can be serialized.");
} }
@ -292,14 +292,14 @@ namespace LeanCloud {
internal Task SaveExternal() { internal Task SaveExternal() {
Dictionary<string, object> strs = new Dictionary<string, object>() Dictionary<string, object> strs = new Dictionary<string, object>()
{ {
{ "url", this.Url.ToString() }, { "url", Url.ToString() },
{ "name",this.Name }, { "name", Name },
{ "mime_type",this.MimeType}, { "mime_type", MimeType},
{ "metaData",this.MetaData} { "metaData", MetaData}
}; };
AVCommand cmd = null; AVCommand cmd = null;
if (!string.IsNullOrEmpty(this.ObjectId)) { if (!string.IsNullOrEmpty(ObjectId)) {
cmd = new AVCommand { cmd = new AVCommand {
Path = $"files/{ObjectId}", Path = $"files/{ObjectId}",
Method = HttpMethod.Put, Method = HttpMethod.Put,
@ -331,7 +331,7 @@ namespace LeanCloud {
public string ObjectId { public string ObjectId {
get { get {
string str; string str;
lock (this.mutex) { lock (mutex) {
str = state.ObjectId; str = state.ObjectId;
} }
return str; return str;
@ -359,8 +359,7 @@ namespace LeanCloud {
} }
static AVFile() { static AVFile() {
Dictionary<string, string> strs = new Dictionary<string, string>() Dictionary<string, string> strs = new Dictionary<string, string> {
{
{ "ai", "application/postscript" }, { "ai", "application/postscript" },
{ "aif", "audio/x-aiff" }, { "aif", "audio/x-aiff" },
{ "aifc", "audio/x-aiff" }, { "aifc", "audio/x-aiff" },
@ -550,15 +549,15 @@ namespace LeanCloud {
{ "xyz", "chemical/x-xyz" }, { "xyz", "chemical/x-xyz" },
{ "zip", "application/zip" }, { "zip", "application/zip" },
}; };
AVFile.MIMETypesDictionary = strs; MIMETypesDictionary = strs;
} }
internal static string GetMIMEType(string fileName) { internal static string GetMIMEType(string fileName) {
try { try {
string str = Path.GetExtension(fileName).Remove(0, 1); string str = Path.GetExtension(fileName).Remove(0, 1);
if (!AVFile.MIMETypesDictionary.ContainsKey(str)) { if (!MIMETypesDictionary.ContainsKey(str)) {
return "unknown/unknown"; return "unknown/unknown";
} }
return AVFile.MIMETypesDictionary[str]; return MIMETypesDictionary[str];
} catch { } catch {
return "unknown/unknown"; return "unknown/unknown";
} }
@ -585,11 +584,12 @@ namespace LeanCloud {
} }
public static AVFile CreateWithData(string objectId, string name, string url, IDictionary<string, object> metaData) { public static AVFile CreateWithData(string objectId, string name, string url, IDictionary<string, object> metaData) {
var fileState = new FileState(); var fileState = new FileState {
fileState.Name = name; Name = name,
fileState.ObjectId = objectId; ObjectId = objectId,
fileState.Url = new Uri(url); Url = new Uri(url),
fileState.MetaData = metaData; MetaData = metaData
};
return CreateWithState(fileState); return CreateWithState(fileState);
} }
/// <summary> /// <summary>
@ -602,7 +602,7 @@ namespace LeanCloud {
} }
internal void MergeFromJSON(IDictionary<string, object> jsonData) { internal void MergeFromJSON(IDictionary<string, object> jsonData) {
lock (this.mutex) { lock (mutex) {
state.ObjectId = jsonData["objectId"] as string; state.ObjectId = jsonData["objectId"] as string;
state.Url = new Uri(jsonData["url"] as string, UriKind.Absolute); state.Url = new Uri(jsonData["url"] as string, UriKind.Absolute);
if (jsonData.ContainsKey("name")) { if (jsonData.ContainsKey("name")) {

View File

@ -4,8 +4,6 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Linq; using System.Linq;
using System.Net;
using System.Reflection;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -13,19 +11,8 @@ using System.Collections;
namespace LeanCloud { namespace LeanCloud {
/// <summary> /// <summary>
/// The AVObject is a local representation of data that can be saved and /// AVObject
/// retrieved from the LeanCloud cloud.</summary> /// </summary>
/// <remarks>
/// <para>
/// The basic workflow for creating new data is to construct a new AVObject,
/// use the indexer to fill it with data, and then use SaveAsync() to persist to the
/// database.
/// </para>
/// <para>
/// The basic workflow for accessing existing data is to use a AVQuery
/// to specify which existing data to retrieve.
/// </para>
/// </remarks>
public class AVObject : IEnumerable<KeyValuePair<string, object>>, INotifyPropertyChanged, INotifyPropertyUpdated, INotifyCollectionPropertyUpdated { public class AVObject : IEnumerable<KeyValuePair<string, object>>, INotifyPropertyChanged, INotifyPropertyUpdated, INotifyCollectionPropertyUpdated {
private static readonly string AutoClassName = "_Automatic"; private static readonly string AutoClassName = "_Automatic";
@ -615,7 +602,7 @@ string propertyName
var saveDirtyFileTasks = DeepTraversal(obj, true) var saveDirtyFileTasks = DeepTraversal(obj, true)
.OfType<AVFile>() .OfType<AVFile>()
.Where(f => f.IsDirty) .Where(f => f.IsDirty)
.Select(f => f.SaveAsync(cancellationToken)).ToList(); .Select(f => f.SaveAsync(cancellationToken: cancellationToken)).ToList();
return Task.WhenAll(saveDirtyFileTasks).OnSuccess(_ => { return Task.WhenAll(saveDirtyFileTasks).OnSuccess(_ => {
IEnumerable<AVObject> remaining = new List<AVObject>(uniqueObjects); IEnumerable<AVObject> remaining = new List<AVObject>(uniqueObjects);
@ -740,7 +727,7 @@ string propertyName
/// <returns>The list passed in for convenience.</returns> /// <returns>The list passed in for convenience.</returns>
public static Task<IEnumerable<T>> FetchAllIfNeededAsync<T>( public static Task<IEnumerable<T>> FetchAllIfNeededAsync<T>(
IEnumerable<T> objects, CancellationToken cancellationToken) where T : AVObject { IEnumerable<T> objects, CancellationToken cancellationToken) where T : AVObject {
return AVObject.EnqueueForAll(objects.Cast<AVObject>(), (Task toAwait) => { return EnqueueForAll(objects.Cast<AVObject>(), (Task toAwait) => {
return FetchAllInternalAsync(objects, false, toAwait, cancellationToken); return FetchAllInternalAsync(objects, false, toAwait, cancellationToken);
}, cancellationToken); }, cancellationToken);
} }
@ -763,7 +750,7 @@ string propertyName
/// <returns>The list passed in for convenience.</returns> /// <returns>The list passed in for convenience.</returns>
public static Task<IEnumerable<T>> FetchAllAsync<T>( public static Task<IEnumerable<T>> FetchAllAsync<T>(
IEnumerable<T> objects, CancellationToken cancellationToken) where T : AVObject { IEnumerable<T> objects, CancellationToken cancellationToken) where T : AVObject {
return AVObject.EnqueueForAll(objects.Cast<AVObject>(), (Task toAwait) => { return EnqueueForAll(objects.Cast<AVObject>(), (Task toAwait) => {
return FetchAllInternalAsync(objects, true, toAwait, cancellationToken); return FetchAllInternalAsync(objects, true, toAwait, cancellationToken);
}, cancellationToken); }, cancellationToken);
} }
@ -872,7 +859,7 @@ string propertyName
var uniqueObjects = new HashSet<AVObject>(objects.OfType<AVObject>().ToList(), var uniqueObjects = new HashSet<AVObject>(objects.OfType<AVObject>().ToList(),
new IdentityEqualityComparer<AVObject>()); new IdentityEqualityComparer<AVObject>());
return AVObject.EnqueueForAll<object>(uniqueObjects, toAwait => { return EnqueueForAll<object>(uniqueObjects, toAwait => {
var states = uniqueObjects.Select(t => t.state).ToList(); var states = uniqueObjects.Select(t => t.state).ToList();
return toAwait.OnSuccess(_ => { return toAwait.OnSuccess(_ => {
var deleteTasks = ObjectController.DeleteAllAsync(states, cancellationToken); var deleteTasks = ObjectController.DeleteAllAsync(states, cancellationToken);