Merge pull request #120 from onerain88/api-doc

API Doc
oneRain 2021-04-21 15:03:41 +08:00 committed by GitHub
commit 2b79e9325d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
55 changed files with 817 additions and 43 deletions

View File

@ -10,6 +10,10 @@ namespace LeanCloud.Engine {
AfterDelete AfterDelete
} }
/// <summary>
/// LCEngineClassHookAttribute is an attribute that hooks class in LeanEngine.
/// </summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class LCEngineClassHookAttribute : Attribute { public class LCEngineClassHookAttribute : Attribute {
public string ClassName { public string ClassName {
get; get;

View File

@ -1,6 +1,9 @@
using System; using System;
namespace LeanCloud.Engine { namespace LeanCloud.Engine {
/// <summary>
/// LCEngineFunctionAttribute is an attribute of cloud function in engine.
/// </summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class LCEngineFunctionAttribute : Attribute { public class LCEngineFunctionAttribute : Attribute {
public string FunctionName { public string FunctionName {

View File

@ -1,6 +1,9 @@
using System; using System;
namespace LeanCloud.Engine { namespace LeanCloud.Engine {
/// <summary>
/// LCEngineFunctionParamAttribute is an attribute of the parameter of cloud function in engine.
/// </summary>
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)]
public class LCEngineFunctionParamAttribute : Attribute { public class LCEngineFunctionParamAttribute : Attribute {
public string ParamName { public string ParamName {

View File

@ -20,6 +20,10 @@ namespace LeanCloud.Engine {
ClientOffline, ClientOffline,
} }
/// <summary>
/// LCEngineRealtimeHookAttribute is an attribute that hooks realtime in engine.
/// </summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class LCEngineRealtimeHookAttribute : Attribute { public class LCEngineRealtimeHookAttribute : Attribute {
public LCEngineRealtimeHookType HookType { public LCEngineRealtimeHookType HookType {
get; get;

View File

@ -7,6 +7,10 @@ namespace LeanCloud.Engine {
OnLogin OnLogin
} }
/// <summary>
/// LCEngineUserHookAttribute is an attribute that hooks user in engine.
/// </summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class LCEngineUserHookAttribute : Attribute { public class LCEngineUserHookAttribute : Attribute {
public LCEngineUserHookType HookType { public LCEngineUserHookType HookType {
get; get;

View File

@ -11,6 +11,9 @@ using Microsoft.Extensions.DependencyInjection;
using LeanCloud.Common; using LeanCloud.Common;
namespace LeanCloud.Engine { namespace LeanCloud.Engine {
/// <summary>
/// LCEngine provides the initialization of LeanEngine.
/// </summary>
public class LCEngine { public class LCEngine {
public const string LCEngineCORS = "LCEngineCORS"; public const string LCEngineCORS = "LCEngineCORS";
@ -79,6 +82,10 @@ namespace LeanCloud.Engine {
public static Dictionary<string, MethodInfo> ClassHooks = new Dictionary<string, MethodInfo>(); public static Dictionary<string, MethodInfo> ClassHooks = new Dictionary<string, MethodInfo>();
public static Dictionary<string, MethodInfo> UserHooks = new Dictionary<string, MethodInfo>(); public static Dictionary<string, MethodInfo> UserHooks = new Dictionary<string, MethodInfo>();
/// <summary>
/// Initializes the engine with the given services.
/// </summary>
/// <param name="services"></param>
public static void Initialize(IServiceCollection services) { public static void Initialize(IServiceCollection services) {
// 获取环境变量 // 获取环境变量
LCLogger.Debug("-------------------------------------------------"); LCLogger.Debug("-------------------------------------------------");
@ -198,7 +205,7 @@ namespace LeanCloud.Engine {
}); });
} }
public static void PrintEnvironmentVar(string key) { private static void PrintEnvironmentVar(string key) {
LCLogger.Debug($"{key} : {Environment.GetEnvironmentVariable(key)}"); LCLogger.Debug($"{key} : {Environment.GetEnvironmentVariable(key)}");
} }
@ -293,7 +300,7 @@ namespace LeanCloud.Engine {
} }
} }
public static object GetFunctions(HttpRequest request) { internal static object GetFunctions(HttpRequest request) {
CheckMasterKey(request); CheckMasterKey(request);
List<string> functions = new List<string>(); List<string> functions = new List<string>();

View File

@ -1,9 +1,11 @@
using System; using System.Collections.Generic;
using System.Collections.Generic;
using System.Threading; using System.Threading;
using LeanCloud.Storage; using LeanCloud.Storage;
namespace LeanCloud.Engine { namespace LeanCloud.Engine {
/// <summary>
/// LCEngineRequestContext provides the context of engine request.
/// </summary>
public class LCEngineRequestContext { public class LCEngineRequestContext {
public const string RemoteAddressKey = "__remoteAddressKey"; public const string RemoteAddressKey = "__remoteAddressKey";
public const string SessionTokenKey = "__sessionToken"; public const string SessionTokenKey = "__sessionToken";
@ -31,7 +33,10 @@ namespace LeanCloud.Engine {
} }
return requestContext.Value[key]; return requestContext.Value[key];
} }
/// <summary>
/// The remote address of this request.
/// </summary>
public static string RemoteAddress { public static string RemoteAddress {
get { get {
object remoteAddress = Get(RemoteAddressKey); object remoteAddress = Get(RemoteAddressKey);
@ -45,6 +50,9 @@ namespace LeanCloud.Engine {
} }
} }
/// <summary>
/// The session token of this request.
/// </summary>
public static string SessionToken { public static string SessionToken {
get { get {
object sessionToken = Get(SessionTokenKey); object sessionToken = Get(SessionTokenKey);
@ -58,6 +66,9 @@ namespace LeanCloud.Engine {
} }
} }
/// <summary>
/// The user of this request.
/// </summary>
public static LCUser CurrentUser { public static LCUser CurrentUser {
get { get {
object currentUser = Get(CurrentUserKey); object currentUser = Get(CurrentUserKey);

View File

@ -10,7 +10,7 @@ using LeanCloud.LiveQuery.Internal;
namespace LeanCloud.LiveQuery { namespace LeanCloud.LiveQuery {
/// <summary> /// <summary>
/// LiveQuery /// LeanCloud LiveQuery.
/// </summary> /// </summary>
public class LCLiveQuery { public class LCLiveQuery {
/// <summary> /// <summary>

View File

@ -2,7 +2,15 @@
using LeanCloud.Storage; using LeanCloud.Storage;
namespace LeanCloud.LiveQuery { namespace LeanCloud.LiveQuery {
/// <summary>
/// LCQueryExtension is the extension of a LCQuery.
/// </summary>
public static class LCQueryExtension { public static class LCQueryExtension {
/// <summary>
/// Subscribes a LCQuery.
/// </summary>
/// <param name="query"></param>
/// <returns></returns>
public static async Task<LCLiveQuery> Subscribe(this LCQuery query) { public static async Task<LCLiveQuery> Subscribe(this LCQuery query) {
LCLiveQuery liveQuery = new LCLiveQuery { LCLiveQuery liveQuery = new LCLiveQuery {
Query = query Query = query

View File

@ -5,7 +5,7 @@ using System.Threading.Tasks;
namespace LeanCloud.Realtime { namespace LeanCloud.Realtime {
/// <summary> /// <summary>
/// Chatroom /// LCIMChatRoom is a local representation of chatroom in LeanCloud.
/// </summary> /// </summary>
public class LCIMChatRoom : LCIMConversation { public class LCIMChatRoom : LCIMConversation {
public LCIMChatRoom(LCIMClient client) : public LCIMChatRoom(LCIMClient client) :
@ -25,14 +25,29 @@ namespace LeanCloud.Realtime {
return await Client.ConversationController.GetOnlineMembers(Id, limit); return await Client.ConversationController.GetOnlineMembers(Id, limit);
} }
/// <summary>
/// Adds members to this conversation.
/// </summary>
/// <param name="clientIds"></param>
/// <returns></returns>
public override Task<LCIMPartiallySuccessResult> AddMembers(IEnumerable<string> clientIds) { public override Task<LCIMPartiallySuccessResult> AddMembers(IEnumerable<string> clientIds) {
throw new Exception("Add members is not allowed in chat room."); throw new Exception("Add members is not allowed in chat room.");
} }
/// <summary>
/// Flags the read status of this conversation.
/// But it is an no-op in LCIMChatRoom.
/// </summary>
/// <returns></returns>
public override Task Read() { public override Task Read() {
return Task.CompletedTask; return Task.CompletedTask;
} }
/// <summary>
/// Fetchs the recipt timestamps of this conversation.
/// But it is an no-op in LCIMChatRoom.
/// </summary>
/// <returns></returns>
public override Task FetchReciptTimestamps() { public override Task FetchReciptTimestamps() {
return Task.CompletedTask; return Task.CompletedTask;
} }

View File

@ -6,7 +6,8 @@ using System.Collections.ObjectModel;
namespace LeanCloud.Realtime { namespace LeanCloud.Realtime {
/// <summary> /// <summary>
/// Conversation /// LCIMConversation is a local representation of general conversation
/// in LeanCloud.
/// </summary> /// </summary>
public class LCIMConversation { public class LCIMConversation {
/// <summary> /// <summary>

View File

@ -1,4 +1,7 @@
namespace LeanCloud.Realtime { namespace LeanCloud.Realtime {
/// <summary>
/// LCIMConversationMemberInfo represents the member info of the conversation.
/// </summary>
public class LCIMConversationMemberInfo { public class LCIMConversationMemberInfo {
public const string Owner = "Owner"; public const string Owner = "Owner";

View File

@ -3,10 +3,12 @@ using System.Collections;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using LeanCloud.Storage.Internal.Query; using LeanCloud.Storage.Internal.Query;
using System.Linq; using System.Linq;
using System.Collections.Generic;
using System; using System;
namespace LeanCloud.Realtime { namespace LeanCloud.Realtime {
/// <summary>
/// LCIMConversationQuery is the query for conversations.
/// </summary>
public class LCIMConversationQuery { public class LCIMConversationQuery {
internal const int CompactFlag = 0x1; internal const int CompactFlag = 0x1;
internal const int WithLastMessageFlag = 0x2; internal const int WithLastMessageFlag = 0x2;

View File

@ -1,6 +1,9 @@
using System; using System;
namespace LeanCloud.Realtime { namespace LeanCloud.Realtime {
/// <summary>
/// LCIMMessageQueryEndpoint limits the query results.
/// </summary>
public class LCIMMessageQueryEndpoint { public class LCIMMessageQueryEndpoint {
public string MessageId { public string MessageId {
get; set; get; set;

View File

@ -2,6 +2,10 @@
using System.Threading.Tasks; using System.Threading.Tasks;
namespace LeanCloud.Realtime { namespace LeanCloud.Realtime {
/// <summary>
/// LCIMServiceConversation is a local representation of service conversation
/// in LeanCloud.
/// </summary>
public class LCIMServiceConversation : LCIMConversation { public class LCIMServiceConversation : LCIMConversation {
public LCIMServiceConversation(LCIMClient client) : base(client) { public LCIMServiceConversation(LCIMClient client) : base(client) {
} }

View File

@ -1,6 +1,10 @@
using System; using System;
namespace LeanCloud.Realtime { namespace LeanCloud.Realtime {
/// <summary>
/// LCIMTemporaryConversation is a local representation of temporary conversation
/// in LeanCloud.
/// </summary>
public class LCIMTemporaryConversation : LCIMConversation { public class LCIMTemporaryConversation : LCIMConversation {
public DateTime ExpiredAt { public DateTime ExpiredAt {
get; get;

View File

@ -8,7 +8,9 @@ using LeanCloud.Realtime.Internal.Protocol;
using LeanCloud.Realtime.Internal.Controller; using LeanCloud.Realtime.Internal.Controller;
namespace LeanCloud.Realtime { namespace LeanCloud.Realtime {
/// <summary>
/// LCIMClient is a local representation of realtime client in LeanCloud.
/// </summary>
public class LCIMClient { public class LCIMClient {
/// <summary> /// <summary>
/// Conversation cache /// Conversation cache
@ -29,6 +31,9 @@ namespace LeanCloud.Realtime {
get; private set; get; private set;
} }
/// <summary>
/// Device Id
/// </summary>
public string DeviceId { public string DeviceId {
get; private set; get; private set;
} }
@ -235,6 +240,13 @@ namespace LeanCloud.Realtime {
#region 接口 #region 接口
/// <summary>
/// Constructs a LCIMClient with client id.
/// </summary>
/// <param name="clientId"></param>
/// <param name="tag"></param>
/// <param name="deviceId"></param>
/// <param name="signatureFactory"></param>
public LCIMClient(string clientId, public LCIMClient(string clientId,
string tag = null, string tag = null,
string deviceId = null, string deviceId = null,
@ -245,6 +257,13 @@ namespace LeanCloud.Realtime {
SetUpClient(clientId, tag, deviceId, signatureFactory); SetUpClient(clientId, tag, deviceId, signatureFactory);
} }
/// <summary>
/// Constructs a LCIMClient with a LCUser.
/// </summary>
/// <param name="user"></param>
/// <param name="tag"></param>
/// <param name="deviceId"></param>
/// <param name="signatureFactory"></param>
public LCIMClient(LCUser user, public LCIMClient(LCUser user,
string tag = null, string tag = null,
string deviceId = null, string deviceId = null,

View File

@ -2,6 +2,9 @@
using LeanCloud.Realtime.Internal.Connection; using LeanCloud.Realtime.Internal.Connection;
namespace LeanCloud.Realtime { namespace LeanCloud.Realtime {
/// <summary>
/// LCRealtime contains static functions that handle the global connection.
/// </summary>
public class LCRealtime { public class LCRealtime {
/// <summary> /// <summary>
/// Every application uses a connection. /// Every application uses a connection.

View File

@ -2,6 +2,9 @@
using LeanCloud.Storage; using LeanCloud.Storage;
namespace LeanCloud.Realtime { namespace LeanCloud.Realtime {
/// <summary>
/// LCIMAudioMessage is a local representation of audio message in LeanCloud.
/// </summary>
public class LCIMAudioMessage : LCIMFileMessage { public class LCIMAudioMessage : LCIMFileMessage {
public double Duration { public double Duration {
get; private set; get; private set;

View File

@ -1,4 +1,7 @@
namespace LeanCloud.Realtime { namespace LeanCloud.Realtime {
/// <summary>
/// LCIMBinaryMessage is a local representation of binary message in LeanCloud.
/// </summary>
public class LCIMBinaryMessage : LCIMMessage { public class LCIMBinaryMessage : LCIMMessage {
public byte[] Data { public byte[] Data {
get; internal set; get; internal set;

View File

@ -5,6 +5,9 @@ using LeanCloud.Storage;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace LeanCloud.Realtime { namespace LeanCloud.Realtime {
/// <summary>
/// LCIMFileMessage is a local representation of file message in LeanCloud.
/// </summary>
public class LCIMFileMessage : LCIMTextMessage { public class LCIMFileMessage : LCIMTextMessage {
public LCFile File { public LCFile File {
get; set; get; set;

View File

@ -2,6 +2,9 @@
using LeanCloud.Storage; using LeanCloud.Storage;
namespace LeanCloud.Realtime { namespace LeanCloud.Realtime {
/// <summary>
/// LCIMImageMessage is a local representation of image message in LeanCloud.
/// </summary>
public class LCIMImageMessage : LCIMFileMessage { public class LCIMImageMessage : LCIMFileMessage {
public int Width { public int Width {
get; private set; get; private set;

View File

@ -3,6 +3,9 @@ using System.Collections.Generic;
using LeanCloud.Storage; using LeanCloud.Storage;
namespace LeanCloud.Realtime { namespace LeanCloud.Realtime {
/// <summary>
/// LCIMLocationMessage is a local representation of location message in LeanCloud.
/// </summary>
public class LCIMLocationMessage : LCIMTextMessage { public class LCIMLocationMessage : LCIMTextMessage {
public LCGeoPoint Location { public LCGeoPoint Location {
get; set; get; set;

View File

@ -1,6 +1,9 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace LeanCloud.Realtime { namespace LeanCloud.Realtime {
/// <summary>
/// LCIMTextMessage is a local representation of text message in LeanCloud.
/// </summary>
public class LCIMTextMessage : LCIMTypedMessage { public class LCIMTextMessage : LCIMTypedMessage {
public string Text { public string Text {
get; set; get; set;

View File

@ -2,6 +2,9 @@
using LeanCloud.Storage; using LeanCloud.Storage;
namespace LeanCloud.Realtime { namespace LeanCloud.Realtime {
/// <summary>
/// LCIMVideoMessage is a local representation of video message in LeanCloud.
/// </summary>
public class LCIMVideoMessage : LCIMFileMessage { public class LCIMVideoMessage : LCIMFileMessage {
public int Width { public int Width {
get; private set; get; private set;

View File

@ -1,6 +1,9 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace LeanCloud.Realtime { namespace LeanCloud.Realtime {
/// <summary>
/// LCIMOperationFailure is the failed result of a conversation operation.
/// </summary>
public class LCIMOperationFailure { public class LCIMOperationFailure {
public int Code { public int Code {
get; set; get; set;

View File

@ -1,6 +1,9 @@
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
namespace LeanCloud.Realtime { namespace LeanCloud.Realtime {
/// <summary>
/// LCIMPageResult represents the query results.
/// </summary>
public class LCIMPageResult { public class LCIMPageResult {
public ReadOnlyCollection<string> Results { public ReadOnlyCollection<string> Results {
get; internal set; get; internal set;

View File

@ -1,6 +1,9 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace LeanCloud.Realtime { namespace LeanCloud.Realtime {
/// <summary>
/// LCIMPartiallySuccessResult is the partially successful result of a conversation operation.
/// </summary>
public class LCIMPartiallySuccessResult { public class LCIMPartiallySuccessResult {
public List<string> SuccessfulClientIdList { public List<string> SuccessfulClientIdList {
get; internal set; get; internal set;

View File

@ -2,6 +2,9 @@
using System.Threading.Tasks; using System.Threading.Tasks;
namespace LeanCloud.Realtime { namespace LeanCloud.Realtime {
/// <summary>
/// ILCIMSignatureFactory is an interface that creates a LCRealtime signature.
/// </summary>
public interface ILCIMSignatureFactory { public interface ILCIMSignatureFactory {
Task<LCIMSignature> CreateConnectSignature(string clientId); Task<LCIMSignature> CreateConnectSignature(string clientId);

View File

@ -1,4 +1,7 @@
namespace LeanCloud.Realtime { namespace LeanCloud.Realtime {
/// <summary>
/// LCIMSignature represents a LCRealtime signature.
/// </summary>
public class LCIMSignature { public class LCIMSignature {
public string Signature { public string Signature {
get; set; get; set;

View File

@ -56,9 +56,6 @@
<Compile Include="..\Storage\Public\LCGeoPoint.cs"> <Compile Include="..\Storage\Public\LCGeoPoint.cs">
<Link>Storage\Public\LCGeoPoint.cs</Link> <Link>Storage\Public\LCGeoPoint.cs</Link>
</Compile> </Compile>
<Compile Include="..\Storage\Public\LCStorage.cs">
<Link>Storage\Public\LCStorage.cs</Link>
</Compile>
<Compile Include="..\Storage\Public\LCUserAuthDataLoginOption.cs"> <Compile Include="..\Storage\Public\LCUserAuthDataLoginOption.cs">
<Link>Storage\Public\LCUserAuthDataLoginOption.cs</Link> <Link>Storage\Public\LCUserAuthDataLoginOption.cs</Link>
</Compile> </Compile>
@ -155,5 +152,8 @@
<Compile Include="..\Storage\Internal\Query\LCCompositionalCondition.cs"> <Compile Include="..\Storage\Internal\Query\LCCompositionalCondition.cs">
<Link>Storage\Internal\Query\LCCompositionalCondition.cs</Link> <Link>Storage\Internal\Query\LCCompositionalCondition.cs</Link>
</Compile> </Compile>
<Compile Include="..\Storage\Internal\LCStorage.cs">
<Link>Storage\Internal\LCStorage.cs</Link>
</Compile>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -1,5 +1,5 @@
using LeanCloud.Common; using LeanCloud.Common;
using LeanCloud.Storage; using LeanCloud.Storage.Internal;
namespace LeanCloud { namespace LeanCloud {
public class LCApplication { public class LCApplication {

View File

@ -14,6 +14,7 @@ namespace Storage.Test {
[SetUp] [SetUp]
public void SetUp() { public void SetUp() {
LCLogger.LogDelegate += Utils.Print;
LCApplication.Initialize(Utils.AppId, Utils.AppKey, Utils.AppServer, Utils.MasterKey); LCApplication.Initialize(Utils.AppId, Utils.AppKey, Utils.AppServer, Utils.MasterKey);
LCApplication.UseMasterKey = true; LCApplication.UseMasterKey = true;
leaderboardName = $"Leaderboard_{DateTimeOffset.Now.DayOfYear}"; leaderboardName = $"Leaderboard_{DateTimeOffset.Now.DayOfYear}";

View File

@ -1,9 +1,17 @@
using LeanCloud.Common; using LeanCloud.Common;
using LeanCloud.Storage; using LeanCloud.Storage.Internal;
using LeanCloud.Storage.Internal.Persistence; using LeanCloud.Storage.Internal.Persistence;
namespace LeanCloud { namespace LeanCloud {
/// <summary>
/// LCApplication contains static functions that handle global configuration
/// for LeanCloud services.
/// </summary>
public class LCApplication { public class LCApplication {
/// <summary>
/// Uses the master key or not.
/// The default is false.
/// </summary>
public static bool UseMasterKey { public static bool UseMasterKey {
get => LCCore.UseMasterKey; get => LCCore.UseMasterKey;
set { set {
@ -11,6 +19,13 @@ namespace LeanCloud {
} }
} }
/// <summary>
/// Initialize LeanCloud services.
/// </summary>
/// <param name="appId">The application id provided in LeanCloud dashboard.</param>
/// <param name="appKey">The application key provided in LeanCloud dashboard.</param>
/// <param name="server">The server url, typically consist of your own domain.</param>
/// <param name="masterKey">The application master key provided in LeanCloud dashboard.</param>
public static void Initialize(string appId, public static void Initialize(string appId,
string appKey, string appKey,
string server = null, string server = null,

View File

@ -1,7 +1,6 @@
using System; using LeanCloud.Common;
using LeanCloud.Common;
namespace LeanCloud.Storage { namespace LeanCloud.Storage.Internal {
public class LCStorage { public class LCStorage {
private const string SessionHeaderKey = "X-LC-Session"; private const string SessionHeaderKey = "X-LC-Session";

View File

@ -3,21 +3,28 @@ using System.Collections.Generic;
namespace LeanCloud.Storage { namespace LeanCloud.Storage {
/// <summary> /// <summary>
/// LeanCloud Access Control Lists. /// LCACL is used to control which users and roles can access or modify
/// a particular object. Each LCObject can have its own LCACL.
/// </summary> /// </summary>
public class LCACL { public class LCACL {
const string PublicKey = "*"; const string PublicKey = "*";
const string RoleKeyPrefix = "role:"; const string RoleKeyPrefix = "role:";
public Dictionary<string, bool> ReadAccess { internal Dictionary<string, bool> ReadAccess {
get; get;
} = new Dictionary<string, bool>(); } = new Dictionary<string, bool>();
public Dictionary<string, bool> WriteAccess { internal Dictionary<string, bool> WriteAccess {
get; get;
} = new Dictionary<string, bool>(); } = new Dictionary<string, bool>();
/// <summary>
/// Creates a LCACL that is allowed to read and write this object
/// for the user.
/// </summary>
/// <param name="owner">The user.</param>
/// <returns></returns>
public static LCACL CreateWithOwner(LCUser owner) { public static LCACL CreateWithOwner(LCUser owner) {
if (owner == null) { if (owner == null) {
throw new ArgumentNullException(nameof(owner)); throw new ArgumentNullException(nameof(owner));
@ -28,6 +35,9 @@ namespace LeanCloud.Storage {
return acl; return acl;
} }
/// <summary>
/// Gets or sets whether everyone is allowed to read this object.
/// </summary>
public bool PublicReadAccess { public bool PublicReadAccess {
get { get {
return GetAccess(ReadAccess, PublicKey); return GetAccess(ReadAccess, PublicKey);
@ -36,6 +46,9 @@ namespace LeanCloud.Storage {
} }
} }
/// <summary>
/// Gets or sets whether everyone is allowed to write this object.
/// </summary>
public bool PublicWriteAccess { public bool PublicWriteAccess {
get { get {
return GetAccess(WriteAccess, PublicKey); return GetAccess(WriteAccess, PublicKey);
@ -44,6 +57,14 @@ namespace LeanCloud.Storage {
} }
} }
/// <summary>
/// Detects whether the given user id is *explicitly* allowed to read this
/// object. Even if this returns false, the user may still be able to read
/// it if <see cref="PublicReadAccess"/> is true or a role that the user
/// belongs to has read access.
/// </summary>
/// <param name="userId">The user ObjectId to check.</param>
/// <returns></returns>
public bool GetUserIdReadAccess(string userId) { public bool GetUserIdReadAccess(string userId) {
if (string.IsNullOrEmpty(userId)) { if (string.IsNullOrEmpty(userId)) {
throw new ArgumentNullException(nameof(userId)); throw new ArgumentNullException(nameof(userId));
@ -51,6 +72,11 @@ namespace LeanCloud.Storage {
return GetAccess(ReadAccess, userId); return GetAccess(ReadAccess, userId);
} }
/// <summary>
/// Set whether the given user id is allowed to read this object.
/// </summary>
/// <param name="userId">The ObjectId of the user.</param>
/// <param name="value">Whether the user has permission.</param>
public void SetUserIdReadAccess(string userId, bool value) { public void SetUserIdReadAccess(string userId, bool value) {
if (string.IsNullOrEmpty(userId)) { if (string.IsNullOrEmpty(userId)) {
throw new ArgumentNullException(nameof(userId)); throw new ArgumentNullException(nameof(userId));
@ -58,6 +84,13 @@ namespace LeanCloud.Storage {
SetAccess(ReadAccess, userId, value); SetAccess(ReadAccess, userId, value);
} }
/// <summary>
/// Detects whether the given user id is *explicitly* allowed to write this
/// object. Even if this returns false, the user may still be able to write
/// it if <see cref="PublicWriteAccess"/> is true or a role that the user
/// belongs to has read access.
/// </summary>
/// <param name="userId">T
public bool GetUserIdWriteAccess(string userId) { public bool GetUserIdWriteAccess(string userId) {
if (string.IsNullOrEmpty(userId)) { if (string.IsNullOrEmpty(userId)) {
throw new ArgumentNullException(nameof(userId)); throw new ArgumentNullException(nameof(userId));
@ -65,6 +98,11 @@ namespace LeanCloud.Storage {
return GetAccess(WriteAccess, userId); return GetAccess(WriteAccess, userId);
} }
/// <summary>
/// Set whether the given user id is allowed to write this object.
/// </summary>
/// <param name="userId">The ObjectId of the user.</param>
/// <param name="value">Whether the user has permission.</param>
public void SetUserIdWriteAccess(string userId, bool value) { public void SetUserIdWriteAccess(string userId, bool value) {
if (string.IsNullOrEmpty(userId)) { if (string.IsNullOrEmpty(userId)) {
throw new ArgumentNullException(nameof(userId)); throw new ArgumentNullException(nameof(userId));
@ -72,6 +110,14 @@ namespace LeanCloud.Storage {
SetAccess(WriteAccess, userId, value); SetAccess(WriteAccess, userId, value);
} }
/// <summary>
/// Detects whether the given user is *explicitly* allowed to read this
/// object. Even if this returns false, the user may still be able to read
/// it if <see cref="PublicReadAccess"/> is true or a role that the user
/// belongs to has read access.
/// </summary>
/// <param name="user">The user to check.</param>
/// <returns></returns>
public bool GetUserReadAccess(LCUser user) { public bool GetUserReadAccess(LCUser user) {
if (user == null) { if (user == null) {
throw new ArgumentNullException(nameof(user)); throw new ArgumentNullException(nameof(user));
@ -79,6 +125,11 @@ namespace LeanCloud.Storage {
return GetUserIdReadAccess(user.ObjectId); return GetUserIdReadAccess(user.ObjectId);
} }
/// <summary>
/// Set whether the given user is allowed to read this object.
/// </summary>
/// <param name="user">The user.</param>
/// <param name="value">Whether the user has permission.</param>
public void SetUserReadAccess(LCUser user, bool value) { public void SetUserReadAccess(LCUser user, bool value) {
if (user == null) { if (user == null) {
throw new ArgumentNullException(nameof(user)); throw new ArgumentNullException(nameof(user));
@ -86,6 +137,14 @@ namespace LeanCloud.Storage {
SetUserIdReadAccess(user.ObjectId, value); SetUserIdReadAccess(user.ObjectId, value);
} }
/// <summary>
/// Detects whether the given user is *explicitly* allowed to write this
/// object. Even if this returns false, the user may still be able to write
/// it if <see cref="PublicReadAccess"/> is true or a role that the user
/// belongs to has write access.
/// </summary>
/// <param name="userId">The user to check.</param>
/// <returns></returns>
public bool GetUserWriteAccess(LCUser user) { public bool GetUserWriteAccess(LCUser user) {
if (user == null) { if (user == null) {
throw new ArgumentNullException(nameof(user)); throw new ArgumentNullException(nameof(user));
@ -93,6 +152,11 @@ namespace LeanCloud.Storage {
return GetUserIdWriteAccess(user.ObjectId); return GetUserIdWriteAccess(user.ObjectId);
} }
/// <summary>
/// Set whether the given user is allowed to write this object.
/// </summary>
/// <param name="user">The user.</param>
/// <param name="value">Whether the user has permission.</param>
public void SetUserWriteAccess(LCUser user, bool value) { public void SetUserWriteAccess(LCUser user, bool value) {
if (user == null) { if (user == null) {
throw new ArgumentNullException(nameof(user)); throw new ArgumentNullException(nameof(user));
@ -100,6 +164,11 @@ namespace LeanCloud.Storage {
SetUserIdWriteAccess(user.ObjectId, value); SetUserIdWriteAccess(user.ObjectId, value);
} }
/// <summary>
/// Detects whether the given role are allowed to read this object.
/// </summary>
/// <param name="role">The role to check.</param>
/// <returns></returns>
public bool GetRoleReadAccess(LCRole role) { public bool GetRoleReadAccess(LCRole role) {
if (role == null) { if (role == null) {
throw new ArgumentNullException(nameof(role)); throw new ArgumentNullException(nameof(role));
@ -108,6 +177,11 @@ namespace LeanCloud.Storage {
return GetAccess(ReadAccess, roleKey); return GetAccess(ReadAccess, roleKey);
} }
/// <summary>
/// Sets whether the given role are allowed to read this object.
/// </summary>
/// <param name="role">The role.</param>
/// <param name="value">Whether the role has access.</param>
public void SetRoleReadAccess(LCRole role, bool value) { public void SetRoleReadAccess(LCRole role, bool value) {
if (role == null) { if (role == null) {
throw new ArgumentNullException(nameof(role)); throw new ArgumentNullException(nameof(role));
@ -116,6 +190,11 @@ namespace LeanCloud.Storage {
SetAccess(ReadAccess, roleKey, value); SetAccess(ReadAccess, roleKey, value);
} }
/// <summary>
/// Detects whether the given role are allowed to write this object.
/// </summary>
/// <param name="role">The role to check.</param>
/// <returns></returns>
public bool GetRoleWriteAccess(LCRole role) { public bool GetRoleWriteAccess(LCRole role) {
if (role == null) { if (role == null) {
throw new ArgumentNullException(nameof(role)); throw new ArgumentNullException(nameof(role));
@ -124,6 +203,11 @@ namespace LeanCloud.Storage {
return GetAccess(WriteAccess, roleKey); return GetAccess(WriteAccess, roleKey);
} }
/// <summary>
/// Sets whether the given role are allowed to write this object.
/// </summary>
/// <param name="role">The role.</param>
/// <param name="value">Whether the role has access.</param>
public void SetRoleWriteAccess(LCRole role, bool value) { public void SetRoleWriteAccess(LCRole role, bool value) {
if (role == null) { if (role == null) {
throw new ArgumentNullException(nameof(role)); throw new ArgumentNullException(nameof(role));

View File

@ -6,7 +6,7 @@ using LeanCloud.Storage.Internal.Object;
namespace LeanCloud.Storage { namespace LeanCloud.Storage {
/// <summary> /// <summary>
/// LeanEngine /// LCCloud contains static functions that call LeanEngine cloud functions.
/// </summary> /// </summary>
public static class LCCloud { public static class LCCloud {
private const string PRODUCTION_KEY = "X-LC-Prod"; private const string PRODUCTION_KEY = "X-LC-Prod";
@ -37,6 +37,13 @@ namespace LeanCloud.Storage {
return response; return response;
} }
/// <summary>
/// Invokes a cloud function.
/// </summary>
/// <typeparam name="T">The type of return value.</typeparam>
/// <param name="name">Cloud function name.</param>
/// <param name="parameters">Parameters of the cloud function.</param>
/// <returns></returns>
public static async Task<T> Run<T>(string name, public static async Task<T> Run<T>(string name,
Dictionary<string, object> parameters = null) { Dictionary<string, object> parameters = null) {
Dictionary<string, object> response = await Run(name, parameters); Dictionary<string, object> response = await Run(name, parameters);

View File

@ -8,9 +8,15 @@ using LeanCloud.Storage.Internal.Object;
using LeanCloud.Storage.Internal.Codec; using LeanCloud.Storage.Internal.Codec;
namespace LeanCloud.Storage { namespace LeanCloud.Storage {
/// <summary>
/// LCFile is a local representation of a LeanCloud file.
/// </summary>
public class LCFile : LCObject { public class LCFile : LCObject {
public const string CLASS_NAME = "_File"; public const string CLASS_NAME = "_File";
/// <summary>
/// Gets the name of the file.
/// </summary>
public string Name { public string Name {
get { get {
return this["name"] as string; return this["name"] as string;
@ -19,6 +25,9 @@ namespace LeanCloud.Storage {
} }
} }
/// <summary>
/// Gets the MIME type of the file.
/// </summary>
public string MimeType { public string MimeType {
get { get {
return this["mime_type"] as string; return this["mime_type"] as string;
@ -27,6 +36,9 @@ namespace LeanCloud.Storage {
} }
} }
/// <summary>
/// Gets the url of the file.
/// </summary>
public string Url { public string Url {
get { get {
return this["url"] as string; return this["url"] as string;
@ -35,6 +47,9 @@ namespace LeanCloud.Storage {
} }
} }
/// <summary>
/// Gets the metadata of the file.
/// </summary>
public Dictionary<string, object> MetaData { public Dictionary<string, object> MetaData {
get { get {
return this["metaData"] as Dictionary<string, object>; return this["metaData"] as Dictionary<string, object>;
@ -45,30 +60,59 @@ namespace LeanCloud.Storage {
readonly Stream stream; readonly Stream stream;
/// <summary>
/// Creates a new file.
/// </summary>
public LCFile() : base(CLASS_NAME) { public LCFile() : base(CLASS_NAME) {
MetaData = new Dictionary<string, object>(); MetaData = new Dictionary<string, object>();
} }
/// <summary>
/// Creates a new file from a byte array.
/// </summary>
/// <param name="name"></param>
/// <param name="bytes"></param>
public LCFile(string name, byte[] bytes) : this() { public LCFile(string name, byte[] bytes) : this() {
Name = name; Name = name;
stream = new MemoryStream(bytes); stream = new MemoryStream(bytes);
} }
/// <summary>
/// Creates a new file from a local file.
/// </summary>
/// <param name="name"></param>
/// <param name="path"></param>
public LCFile(string name, string path) : this() { public LCFile(string name, string path) : this() {
Name = name; Name = name;
MimeType = LCMimeTypeMap.GetMimeType(path); MimeType = LCMimeTypeMap.GetMimeType(path);
stream = new FileStream(path, FileMode.Open); stream = new FileStream(path, FileMode.Open);
} }
/// <summary>
/// Creates a new external file from an url.
/// The file content is saved externally, not copied to LeanCloud.
/// </summary>
/// <param name="name"></param>
/// <param name="url"></param>
public LCFile(string name, Uri url) : this() { public LCFile(string name, Uri url) : this() {
Name = name; Name = name;
Url = url.AbsoluteUri; Url = url.AbsoluteUri;
} }
/// <summary>
/// Adds metadata.
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
public void AddMetaData(string key, object value) { public void AddMetaData(string key, object value) {
MetaData[key] = value; MetaData[key] = value;
} }
/// <summary>
/// Saves the file to LeanCloud.
/// </summary>
/// <param name="onProgress"></param>
/// <returns></returns>
public async Task<LCFile> Save(Action<long, long> onProgress = null) { public async Task<LCFile> Save(Action<long, long> onProgress = null) {
if (!string.IsNullOrEmpty(Url)) { if (!string.IsNullOrEmpty(Url)) {
// 外链方式 // 外链方式
@ -109,6 +153,10 @@ namespace LeanCloud.Storage {
return this; return this;
} }
/// <summary>
/// Deletes the file from LeanCloud.
/// </summary>
/// <returns></returns>
public new async Task Delete() { public new async Task Delete() {
if (string.IsNullOrEmpty(ObjectId)) { if (string.IsNullOrEmpty(ObjectId)) {
return; return;
@ -117,6 +165,15 @@ namespace LeanCloud.Storage {
await LCCore.HttpClient.Delete(path); await LCCore.HttpClient.Delete(path);
} }
/// <summary>
/// Gets the thumbnail url of an image file.
/// </summary>
/// <param name="width"></param>
/// <param name="height"></param>
/// <param name="quality"></param>
/// <param name="scaleToFit"></param>
/// <param name="format"></param>
/// <returns></returns>
public string GetThumbnailUrl(int width, int height, int quality = 100, bool scaleToFit = true, string format = "png") { public string GetThumbnailUrl(int width, int height, int quality = 100, bool scaleToFit = true, string format = "png") {
int mode = scaleToFit ? 2 : 1; int mode = scaleToFit ? 2 : 1;
return $"{Url}?imageView/{mode}/w/{width}/h/{height}/q/{quality}/format/{format}"; return $"{Url}?imageView/{mode}/w/{width}/h/{height}/q/{quality}/format/{format}";
@ -135,6 +192,10 @@ namespace LeanCloud.Storage {
return await LCCore.HttpClient.Post<Dictionary<string, object>>("fileTokens", data: data); return await LCCore.HttpClient.Post<Dictionary<string, object>>("fileTokens", data: data);
} }
/// <summary>
/// Gets LCQuery of LCFile.
/// </summary>
/// <returns></returns>
public static LCQuery<LCFile> GetQuery() { public static LCQuery<LCFile> GetQuery() {
return new LCQuery<LCFile>(CLASS_NAME); return new LCQuery<LCFile>(CLASS_NAME);
} }

View File

@ -1,19 +1,34 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace LeanCloud.Storage { namespace LeanCloud.Storage {
/// <summary>
/// LCFollowersAndFollowees contains followers and followees.
/// </summary>
public class LCFollowersAndFollowees { public class LCFollowersAndFollowees {
/// <summary>
/// The followers.
/// </summary>
public List<LCObject> Followers { public List<LCObject> Followers {
get; internal set; get; internal set;
} }
/// <summary>
/// The followees.
/// </summary>
public List<LCObject> Followees { public List<LCObject> Followees {
get; internal set; get; internal set;
} }
/// <summary>
/// The count of followers.
/// </summary>
public int FollowersCount { public int FollowersCount {
get; internal set; get; internal set;
} }
/// <summary>
/// The count of followees.
/// </summary>
public int FolloweesCount { public int FolloweesCount {
get; internal set; get; internal set;
} }

View File

@ -5,7 +5,16 @@ using LeanCloud.Common;
using LeanCloud.Storage.Internal.Codec; using LeanCloud.Storage.Internal.Codec;
namespace LeanCloud.Storage { namespace LeanCloud.Storage {
/// <summary>
/// LCFriendship contains static functions that handle LCFriendship.
/// </summary>
public static class LCFriendship { public static class LCFriendship {
/// <summary>
/// Requests to add a friend.
/// </summary>
/// <param name="userId">The user id to add.</param>
/// <param name="attributes">The additional attributes for the friendship.</param>
/// <returns></returns>
public static async Task Request(string userId, Dictionary<string, object> attributes = null) { public static async Task Request(string userId, Dictionary<string, object> attributes = null) {
LCUser user = await LCUser.GetCurrent(); LCUser user = await LCUser.GetCurrent();
if (user == null) { if (user == null) {
@ -23,6 +32,12 @@ namespace LeanCloud.Storage {
await LCCore.HttpClient.Post<Dictionary<string, object>>(path, data: data); await LCCore.HttpClient.Post<Dictionary<string, object>>(path, data: data);
} }
/// <summary>
/// Accepts a friend request.
/// </summary>
/// <param name="request">The request.</param>
/// <param name="attributes">The additional attributes for the friendship.</param>
/// <returns></returns>
public static async Task AcceptRequest(LCFriendshipRequest request, Dictionary<string, object> attributes = null) { public static async Task AcceptRequest(LCFriendshipRequest request, Dictionary<string, object> attributes = null) {
if (request == null) { if (request == null) {
throw new ArgumentNullException(nameof(request)); throw new ArgumentNullException(nameof(request));
@ -37,6 +52,11 @@ namespace LeanCloud.Storage {
await LCCore.HttpClient.Put<Dictionary<string, object>>(path, data: data); await LCCore.HttpClient.Put<Dictionary<string, object>>(path, data: data);
} }
/// <summary>
/// Declines a friend request.
/// </summary>
/// <param name="request">The request.</param>
/// <returns></returns>
public static async Task DeclineRequest(LCFriendshipRequest request) { public static async Task DeclineRequest(LCFriendshipRequest request) {
if (request == null) { if (request == null) {
throw new ArgumentNullException(nameof(request)); throw new ArgumentNullException(nameof(request));

View File

@ -1,4 +1,8 @@
namespace LeanCloud.Storage { namespace LeanCloud.Storage {
/// <summary>
/// LCFriendshipRequest is a local representation of a friend request that
/// is saved to LeanCloud.
/// </summary>
public class LCFriendshipRequest : LCObject { public class LCFriendshipRequest : LCObject {
public const string CLASS_NAME = "_FriendshipRequest"; public const string CLASS_NAME = "_FriendshipRequest";

View File

@ -1,26 +1,49 @@
using System; using System;
namespace LeanCloud.Storage { namespace LeanCloud.Storage {
/// <summary>
/// LCGeoPoint represents a geographic location that may be associated
/// with a key in a LCObject or used as a reference point for queries.
/// </summary>
public class LCGeoPoint { public class LCGeoPoint {
/// <summary>
/// Gets the latitude of the LCGeoPoint.
/// </summary>
public double Latitude { public double Latitude {
get; get;
} }
/// <summary>
/// Gets the longitude of the LCGeoPoint.
/// </summary>
public double Longitude { public double Longitude {
get; get;
} }
/// <summary>
/// Constructs a LCGeoPoint with the specified latitude and longitude.
/// </summary>
/// <param name="latitude"></param>
/// <param name="longtitude"></param>
public LCGeoPoint(double latitude, double longtitude) { public LCGeoPoint(double latitude, double longtitude) {
Latitude = latitude; Latitude = latitude;
Longitude = longtitude; Longitude = longtitude;
} }
/// <summary>
/// The original LCGeoPoint.
/// </summary>
public static LCGeoPoint Origin { public static LCGeoPoint Origin {
get { get {
return new LCGeoPoint(0, 0); return new LCGeoPoint(0, 0);
} }
} }
/// <summary>
/// Calculate the distance in kilometers between this point and another GeoPoint.
/// </summary>
/// <param name="point"></param>
/// <returns></returns>
public double KilometersTo(LCGeoPoint point) { public double KilometersTo(LCGeoPoint point) {
if (point == null) { if (point == null) {
throw new ArgumentNullException(nameof(point)); throw new ArgumentNullException(nameof(point));
@ -28,6 +51,11 @@ namespace LeanCloud.Storage {
return RadiansTo(point) * 6371.0; return RadiansTo(point) * 6371.0;
} }
/// <summary>
/// Calculate the distance in miles between this point and another GeoPoint.
/// </summary>
/// <param name="point"></param>
/// <returns></returns>
public double MilesTo(LCGeoPoint point) { public double MilesTo(LCGeoPoint point) {
if (point == null) { if (point == null) {
throw new ArgumentNullException(nameof(point)); throw new ArgumentNullException(nameof(point));
@ -35,6 +63,11 @@ namespace LeanCloud.Storage {
return RadiansTo(point) * 3958.8; return RadiansTo(point) * 3958.8;
} }
/// <summary>
/// Calculate the distance in radians between this point and another GeoPoint.
/// </summary>
/// <param name="point"></param>
/// <returns></returns>
public double RadiansTo(LCGeoPoint point) { public double RadiansTo(LCGeoPoint point) {
if (point == null) { if (point == null) {
throw new ArgumentNullException(nameof(point)); throw new ArgumentNullException(nameof(point));

View File

@ -5,6 +5,9 @@ using System.Linq;
using LeanCloud.Storage.Internal.Operation; using LeanCloud.Storage.Internal.Operation;
namespace LeanCloud.Storage { namespace LeanCloud.Storage {
/// <summary>
/// LCClassHook represents the hooks for saving / updating / deleting LCObject.
/// </summary>
public static class LCClassHook { public static class LCClassHook {
public const string BeforeSave = "beforeSave"; public const string BeforeSave = "beforeSave";
public const string AfterSave = "afterSave"; public const string AfterSave = "afterSave";
@ -17,6 +20,9 @@ namespace LeanCloud.Storage {
public partial class LCObject { public partial class LCObject {
internal const string IgnoreHooksKey = "__ignore_hooks"; internal const string IgnoreHooksKey = "__ignore_hooks";
/// <summary>
/// Disable hooks before saving / updating / deleting LCObject.
/// </summary>
public void DisableBeforeHook() { public void DisableBeforeHook() {
Ignore( Ignore(
LCClassHook.BeforeSave, LCClassHook.BeforeSave,
@ -24,6 +30,9 @@ namespace LeanCloud.Storage {
LCClassHook.BeforeDelete); LCClassHook.BeforeDelete);
} }
/// <summary>
/// Disable hooks after saving / updating / deleting LCObject.
/// </summary>
public void DisableAfterHook() { public void DisableAfterHook() {
Ignore( Ignore(
LCClassHook.AfterSave, LCClassHook.AfterSave,
@ -31,6 +40,10 @@ namespace LeanCloud.Storage {
LCClassHook.AfterDelete); LCClassHook.AfterDelete);
} }
/// <summary>
/// Ignores the hook for this LCObject.
/// </summary>
/// <param name="hookName"></param>
public void IgnoreHook(string hookName) { public void IgnoreHook(string hookName) {
if (hookName != LCClassHook.BeforeSave && hookName != LCClassHook.AfterSave && if (hookName != LCClassHook.BeforeSave && hookName != LCClassHook.AfterSave &&
hookName != LCClassHook.BeforeUpdate && hookName != LCClassHook.AfterUpdate && hookName != LCClassHook.BeforeUpdate && hookName != LCClassHook.AfterUpdate &&
@ -46,6 +59,10 @@ namespace LeanCloud.Storage {
ApplyOperation(IgnoreHooksKey, op); ApplyOperation(IgnoreHooksKey, op);
} }
/// <summary>
/// Gets the updated keys of this LCObject.
/// </summary>
/// <returns></returns>
public ReadOnlyCollection<string> GetUpdatedKeys() { public ReadOnlyCollection<string> GetUpdatedKeys() {
if (this["_updatedKeys"] == null) { if (this["_updatedKeys"] == null) {
return null; return null;

View File

@ -11,51 +11,60 @@ using LeanCloud.Storage.Internal.Codec;
namespace LeanCloud.Storage { namespace LeanCloud.Storage {
/// <summary> /// <summary>
/// LeanCloud Object /// The LCObject is a local representation of data that can be saved and
/// retrieved from the LeanCloud.
/// </summary> /// </summary>
public partial class LCObject { public partial class LCObject {
/// <summary>
/// Last synced data.
/// </summary>
internal LCObjectData data; internal LCObjectData data;
/// <summary>
/// Estimated data.
/// </summary>
internal Dictionary<string, object> estimatedData; internal Dictionary<string, object> estimatedData;
/// <summary>
/// Operations.
/// </summary>
internal Dictionary<string, ILCOperation> operationDict; internal Dictionary<string, ILCOperation> operationDict;
static readonly Dictionary<Type, LCSubclassInfo> subclassTypeDict = new Dictionary<Type, LCSubclassInfo>(); static readonly Dictionary<Type, LCSubclassInfo> subclassTypeDict = new Dictionary<Type, LCSubclassInfo>();
static readonly Dictionary<string, LCSubclassInfo> subclassNameDict = new Dictionary<string, LCSubclassInfo>(); static readonly Dictionary<string, LCSubclassInfo> subclassNameDict = new Dictionary<string, LCSubclassInfo>();
/// <summary>
/// Gets the class name for the LCObject.
/// </summary>
public string ClassName { public string ClassName {
get { get {
return data.ClassName; return data.ClassName;
} }
} }
/// <summary>
/// Gets the object id. An object id is assigned as soon as an object is
/// saved to the server. The combination of a <see cref="ClassName"/> and
/// an <see cref="ObjectId"/> uniquely identifies an object in your application.
/// </summary>
public string ObjectId { public string ObjectId {
get { get {
return data.ObjectId; return data.ObjectId;
} }
} }
/// <summary>
/// Gets the creation time of this object in the cloud.
/// </summary>
public DateTime CreatedAt { public DateTime CreatedAt {
get { get {
return data.CreatedAt; return data.CreatedAt;
} }
} }
/// <summary>
/// Gets the latest update time of this object in the cloud.
/// </summary>
public DateTime UpdatedAt { public DateTime UpdatedAt {
get { get {
return data.UpdatedAt; return data.UpdatedAt;
} }
} }
/// <summary>
/// Gets or sets the LCACL governing this object.
/// </summary>
public LCACL ACL { public LCACL ACL {
get { get {
return this["ACL"] as LCACL ; return this["ACL"] as LCACL ;
@ -72,6 +81,12 @@ namespace LeanCloud.Storage {
} }
} }
/// <summary>
/// Constructs a new LCObject with no data in it. A LCObject constructed
/// in this way will not have an ObjectedId and will not persist in the cloud
/// until <see cref="Save(bool, LCQuery{LCObject}))"/> is called.
/// </summary>
/// <param name="className">The className for the LCObject.</param>
public LCObject(string className) { public LCObject(string className) {
if (string.IsNullOrEmpty(className)) { if (string.IsNullOrEmpty(className)) {
throw new ArgumentNullException(nameof(className)); throw new ArgumentNullException(nameof(className));
@ -84,6 +99,12 @@ namespace LeanCloud.Storage {
isNew = true; isNew = true;
} }
/// <summary>
/// Creates a reference to an existing LCObject.
/// </summary>
/// <param name="className">The className for the LCObject.</param>
/// <param name="objectId">The object id for the LCObject.</param>
/// <returns></returns>
public static LCObject CreateWithoutData(string className, string objectId) { public static LCObject CreateWithoutData(string className, string objectId) {
if (string.IsNullOrEmpty(objectId)) { if (string.IsNullOrEmpty(objectId)) {
throw new ArgumentNullException(nameof(objectId)); throw new ArgumentNullException(nameof(objectId));
@ -94,6 +115,11 @@ namespace LeanCloud.Storage {
return obj; return obj;
} }
/// <summary>
/// Creates a new LCObject.
/// </summary>
/// <param name="className">The className for the LCObject.</param>
/// <returns></returns>
public static LCObject Create(string className) { public static LCObject Create(string className) {
if (subclassNameDict.TryGetValue(className, out LCSubclassInfo subclassInfo)) { if (subclassNameDict.TryGetValue(className, out LCSubclassInfo subclassInfo)) {
return subclassInfo.Constructor.Invoke(); return subclassInfo.Constructor.Invoke();
@ -108,6 +134,12 @@ namespace LeanCloud.Storage {
return null; return null;
} }
/// <summary>
/// Gets or sets a value on the object. It is forbidden to name keys
/// with a leading underscore ('_').
/// </summary>
/// <param name="key">The name of a key.</param>
/// <returns></returns>
public object this[string key] { public object this[string key] {
get { get {
if (estimatedData.TryGetValue(key, out object value)) { if (estimatedData.TryGetValue(key, out object value)) {
@ -148,6 +180,11 @@ namespace LeanCloud.Storage {
} }
/// <summary>
/// Creates a <see cref="LCRelation{T}"/> value for a key.
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
public void AddRelation(string key, LCObject value) { public void AddRelation(string key, LCObject value) {
if (string.IsNullOrEmpty(key)) { if (string.IsNullOrEmpty(key)) {
throw new ArgumentNullException(nameof(key)); throw new ArgumentNullException(nameof(key));
@ -159,6 +196,11 @@ namespace LeanCloud.Storage {
ApplyOperation(key, op); ApplyOperation(key, op);
} }
/// <summary>
/// Removes a <see cref="LCRelation{T}"/> value for a key.
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
public void RemoveRelation(string key, LCObject value) { public void RemoveRelation(string key, LCObject value) {
if (string.IsNullOrEmpty(key)) { if (string.IsNullOrEmpty(key)) {
throw new ArgumentNullException(nameof(key)); throw new ArgumentNullException(nameof(key));
@ -324,6 +366,12 @@ namespace LeanCloud.Storage {
} }
} }
/// <summary>
/// Saves this object to the cloud.
/// </summary>
/// <param name="fetchWhenSave">Whether or not fetch data when saved.</param>
/// <param name="query">The condition for saving.</param>
/// <returns></returns>
public async Task<LCObject> Save(bool fetchWhenSave = false, LCQuery<LCObject> query = null) { public async Task<LCObject> Save(bool fetchWhenSave = false, LCQuery<LCObject> query = null) {
if (LCBatch.HasCircleReference(this, new HashSet<LCObject>())) { if (LCBatch.HasCircleReference(this, new HashSet<LCObject>())) {
throw new ArgumentException("Found a circle dependency when save."); throw new ArgumentException("Found a circle dependency when save.");
@ -350,6 +398,11 @@ namespace LeanCloud.Storage {
return this; return this;
} }
/// <summary>
/// Saves each object in the provided list.
/// </summary>
/// <param name="objects">The objects to save.</param>
/// <returns></returns>
public static async Task<List<LCObject>> SaveAll(IEnumerable<LCObject> objects) { public static async Task<List<LCObject>> SaveAll(IEnumerable<LCObject> objects) {
if (objects == null) { if (objects == null) {
throw new ArgumentNullException(nameof(objects)); throw new ArgumentNullException(nameof(objects));
@ -364,6 +417,10 @@ namespace LeanCloud.Storage {
return objects.ToList(); return objects.ToList();
} }
/// <summary>
/// Deletes this object in the cloud.
/// </summary>
/// <returns></returns>
public async Task Delete() { public async Task Delete() {
if (ObjectId == null) { if (ObjectId == null) {
return; return;
@ -372,6 +429,11 @@ namespace LeanCloud.Storage {
await LCCore.HttpClient.Delete(path); await LCCore.HttpClient.Delete(path);
} }
/// <summary>
/// Deletes each object in the provided list.
/// </summary>
/// <param name="objects"></param>
/// <returns></returns>
public static async Task DeleteAll(IEnumerable<LCObject> objects) { public static async Task DeleteAll(IEnumerable<LCObject> objects) {
if (objects == null || objects.Count() == 0) { if (objects == null || objects.Count() == 0) {
throw new ArgumentNullException(nameof(objects)); throw new ArgumentNullException(nameof(objects));
@ -390,6 +452,12 @@ namespace LeanCloud.Storage {
await LCCore.HttpClient.Post<List<object>>("batch", data: data); await LCCore.HttpClient.Post<List<object>>("batch", data: data);
} }
/// <summary>
/// Fetches this object from the cloud.
/// </summary>
/// <param name="keys">The keys for fetching.</param>
/// <param name="includes">The include keys for fetching.</param>
/// <returns></returns>
public async Task<LCObject> Fetch(IEnumerable<string> keys = null, IEnumerable<string> includes = null) { public async Task<LCObject> Fetch(IEnumerable<string> keys = null, IEnumerable<string> includes = null) {
Dictionary<string, object> queryParams = new Dictionary<string, object>(); Dictionary<string, object> queryParams = new Dictionary<string, object>();
if (keys != null) { if (keys != null) {
@ -405,6 +473,11 @@ namespace LeanCloud.Storage {
return this; return this;
} }
/// <summary>
/// Fetches all of the objects in the provided list.
/// </summary>
/// <param name="objects">The objects for fetching.</param>
/// <returns></returns>
public static async Task<IEnumerable<LCObject>> FetchAll(IEnumerable<LCObject> objects) { public static async Task<IEnumerable<LCObject>> FetchAll(IEnumerable<LCObject> objects) {
if (objects == null || objects.Count() == 0) { if (objects == null || objects.Count() == 0) {
throw new ArgumentNullException(nameof(objects)); throw new ArgumentNullException(nameof(objects));
@ -442,6 +515,13 @@ namespace LeanCloud.Storage {
return objects; return objects;
} }
/// <summary>
/// Registers a custom subclass type with LeanCloud SDK, enabling strong-typing
/// of those LCObjects whenever they appear.
/// </summary>
/// <typeparam name="T">The LCObject subclass type to register.</typeparam>
/// <param name="className">The className on server.</param>
/// <param name="constructor">The constructor for creating an object.</param>
public static void RegisterSubclass<T>(string className, Func<T> constructor) where T : LCObject { public static void RegisterSubclass<T>(string className, Func<T> constructor) where T : LCObject {
Type classType = typeof(T); Type classType = typeof(T);
LCSubclassInfo subclassInfo = new LCSubclassInfo(className, classType, constructor); LCSubclassInfo subclassInfo = new LCSubclassInfo(className, classType, constructor);

View File

@ -9,7 +9,13 @@ using LeanCloud.Storage.Internal.Query;
using LeanCloud.Storage.Internal.Object; using LeanCloud.Storage.Internal.Object;
namespace LeanCloud.Storage { namespace LeanCloud.Storage {
/// <summary>
/// The LCQuery class defines a query that is used to fetch LCObjects.
/// </summary>
public class LCQuery { public class LCQuery {
/// <summary>
/// The classname of this query.
/// </summary>
public string ClassName { public string ClassName {
get; internal set; get; internal set;
} }
@ -18,6 +24,10 @@ namespace LeanCloud.Storage {
get; internal set; get; internal set;
} }
/// <summary>
/// Constructs a LCQuery for class.
/// </summary>
/// <param name="className"></param>
public LCQuery(string className) { public LCQuery(string className) {
ClassName = className; ClassName = className;
Condition = new LCCompositionalCondition(); Condition = new LCCompositionalCondition();
@ -172,16 +182,35 @@ namespace LeanCloud.Storage {
return this; return this;
} }
/// <summary>
/// The value corresponding to key is near the point.
/// </summary>
/// <param name="key"></param>
/// <param name="point"></param>
/// <returns></returns>
public LCQuery<T> WhereNear(string key, LCGeoPoint point) { public LCQuery<T> WhereNear(string key, LCGeoPoint point) {
Condition.WhereNear(key, point); Condition.WhereNear(key, point);
return this; return this;
} }
/// <summary>
/// The value corresponding to key is in the given rectangular geographic bounding box.
/// </summary>
/// <param name="key"></param>
/// <param name="southwest"></param>
/// <param name="northeast"></param>
/// <returns></returns>
public LCQuery<T> WhereWithinGeoBox(string key, LCGeoPoint southwest, LCGeoPoint northeast) { public LCQuery<T> WhereWithinGeoBox(string key, LCGeoPoint southwest, LCGeoPoint northeast) {
Condition.WhereWithinGeoBox(key, southwest, northeast); Condition.WhereWithinGeoBox(key, southwest, northeast);
return this; return this;
} }
/// <summary>
/// The value corresponding to key is related to the parent.
/// </summary>
/// <param name="parent"></param>
/// <param name="key"></param>
/// <returns></returns>
public LCQuery<T> WhereRelatedTo(LCObject parent, string key) { public LCQuery<T> WhereRelatedTo(LCObject parent, string key) {
Condition.WhereRelatedTo(parent, key); Condition.WhereRelatedTo(parent, key);
return this; return this;
@ -255,13 +284,21 @@ namespace LeanCloud.Storage {
return this; return this;
} }
/// <summary>
/// Sorts the results in ascending order by the given key.
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public LCQuery<T> OrderByAscending(string key) { public LCQuery<T> OrderByAscending(string key) {
Condition.OrderByAscending(key); Condition.OrderByAscending(key);
return this; return this;
} }
/// <summary>
/// Sorts the results in descending order by the given key.
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public LCQuery<T> OrderByDescending(string key) { public LCQuery<T> OrderByDescending(string key) {
Condition.OrderByDescending(key); Condition.OrderByDescending(key);
return this; return this;
@ -338,6 +375,10 @@ namespace LeanCloud.Storage {
return this; return this;
} }
/// <summary>
/// Counts the number of objects that match this query.
/// </summary>
/// <returns></returns>
public async Task<int> Count() { public async Task<int> Count() {
string path = $"classes/{ClassName}"; string path = $"classes/{ClassName}";
Dictionary<string, object> parameters = BuildParams(); Dictionary<string, object> parameters = BuildParams();
@ -347,6 +388,12 @@ namespace LeanCloud.Storage {
return (int)ret["count"]; return (int)ret["count"];
} }
/// <summary>
/// Constructs a LCObject whose id is already known by fetching data
/// from the cloud.
/// </summary>
/// <param name="objectId"></param>
/// <returns></returns>
public async Task<T> Get(string objectId) { public async Task<T> Get(string objectId) {
if (string.IsNullOrEmpty(objectId)) { if (string.IsNullOrEmpty(objectId)) {
throw new ArgumentNullException(nameof(objectId)); throw new ArgumentNullException(nameof(objectId));
@ -363,6 +410,10 @@ namespace LeanCloud.Storage {
return DecodeLCObject(response); return DecodeLCObject(response);
} }
/// <summary>
/// Retrieves a list of LCObjects that satisfy the query from Server.
/// </summary>
/// <returns></returns>
public async Task<ReadOnlyCollection<T>> Find() { public async Task<ReadOnlyCollection<T>> Find() {
string path = $"classes/{ClassName}"; string path = $"classes/{ClassName}";
Dictionary<string, object> parameters = BuildParams(); Dictionary<string, object> parameters = BuildParams();
@ -376,6 +427,10 @@ namespace LeanCloud.Storage {
return list.AsReadOnly(); return list.AsReadOnly();
} }
/// <summary>
/// Retrieves at most one LCObject that satisfies this query.
/// </summary>
/// <returns></returns>
public async Task<T> First() { public async Task<T> First() {
Limit(1); Limit(1);
ReadOnlyCollection<T> results = await Find(); ReadOnlyCollection<T> results = await Find();
@ -385,6 +440,11 @@ namespace LeanCloud.Storage {
return null; return null;
} }
/// <summary>
/// Constructs a query that is the and of the given queries.
/// </summary>
/// <param name="queries"></param>
/// <returns></returns>
public static LCQuery<T> And(IEnumerable<LCQuery<T>> queries) { public static LCQuery<T> And(IEnumerable<LCQuery<T>> queries) {
if (queries == null || queries.Count() < 1) { if (queries == null || queries.Count() < 1) {
throw new ArgumentNullException(nameof(queries)); throw new ArgumentNullException(nameof(queries));
@ -402,6 +462,11 @@ namespace LeanCloud.Storage {
return compositionQuery; return compositionQuery;
} }
/// <summary>
/// Constructs a query that is the or of the given queries.
/// </summary>
/// <param name="queries"></param>
/// <returns></returns>
public static LCQuery<T> Or(IEnumerable<LCQuery<T>> queries) { public static LCQuery<T> Or(IEnumerable<LCQuery<T>> queries) {
if (queries == null || queries.Count() < 1) { if (queries == null || queries.Count() < 1) {
throw new ArgumentNullException(nameof(queries)); throw new ArgumentNullException(nameof(queries));

View File

@ -1,21 +1,40 @@
namespace LeanCloud.Storage { namespace LeanCloud.Storage {
/// <summary>
/// LCRelation provides access to all of the children of a many-to-many
/// relationship.
/// </summary>
/// <typeparam name="T">The type of the child objects.</typeparam>
public class LCRelation<T> where T : LCObject { public class LCRelation<T> where T : LCObject {
/// <summary>
/// The key of this LCRelation.
/// </summary>
public string Key { public string Key {
get; set; get; set;
} }
/// <summary>
/// The parent of this LCRelation.
/// </summary>
public LCObject Parent { public LCObject Parent {
get; set; get; set;
} }
/// <summary>
/// The className of this LCRelation.
/// </summary>
public string TargetClass { public string TargetClass {
get; set; get; set;
} }
/// <summary>
/// Constructs a LCRelation.
/// </summary>
public LCRelation() { public LCRelation() {
} }
/// <summary>
/// Gets a query that can be used to query the objects in this relation.
/// </summary>
public LCQuery<T> Query { public LCQuery<T> Query {
get { get {
LCQuery<T> query = new LCQuery<T>(TargetClass); LCQuery<T> query = new LCQuery<T>(TargetClass);

View File

@ -5,7 +5,9 @@
public class LCRole : LCObject { public class LCRole : LCObject {
public const string CLASS_NAME = "_Role"; public const string CLASS_NAME = "_Role";
/// <summary>
/// The name of a LCRole.
/// </summary>
public string Name { public string Name {
get { get {
return this["name"] as string; return this["name"] as string;
@ -40,9 +42,18 @@
} }
} }
/// <summary>
/// Constructs a LCRole.
/// </summary>
public LCRole() : base(CLASS_NAME) { public LCRole() : base(CLASS_NAME) {
} }
/// <summary>
/// Constructs a LCRole with a name and a LCACL.
/// </summary>
/// <param name="name"></param>
/// <param name="acl"></param>
/// <returns></returns>
public static LCRole Create(string name, LCACL acl) { public static LCRole Create(string name, LCACL acl) {
LCRole role = new LCRole() { LCRole role = new LCRole() {
Name = name, Name = name,

View File

@ -61,6 +61,12 @@ namespace LeanCloud.Storage {
await LCCore.HttpClient.Post<Dictionary<string, object>>(path, data: data); await LCCore.HttpClient.Post<Dictionary<string, object>>(path, data: data);
} }
/// <summary>
/// Verifies the mobile number with the verification code.
/// </summary>
/// <param name="mobile"></param>
/// <param name="code"></param>
/// <returns></returns>
public static async Task VerifyMobilePhone(string mobile, string code) { public static async Task VerifyMobilePhone(string mobile, string code) {
string path = $"verifySmsCode/{code}"; string path = $"verifySmsCode/{code}";
Dictionary<string, object> data = new Dictionary<string, object> { Dictionary<string, object> data = new Dictionary<string, object> {

View File

@ -7,6 +7,9 @@ using LeanCloud.Storage.Internal.Object;
using LC.Newtonsoft.Json; using LC.Newtonsoft.Json;
namespace LeanCloud.Storage { namespace LeanCloud.Storage {
/// <summary>
/// LCStatus is a local representation of a status in LeanCloud.
/// </summary>
public class LCStatus : LCObject { public class LCStatus : LCObject {
public const string CLASS_NAME = "_Status"; public const string CLASS_NAME = "_Status";
@ -22,25 +25,42 @@ namespace LeanCloud.Storage {
public const string OwnerKey = "owner"; public const string OwnerKey = "owner";
public const string MessageIdKey = "messageId"; public const string MessageIdKey = "messageId";
/// <summary>
/// The id of this status.
/// </summary>
public int MessageId { public int MessageId {
get; internal set; get; internal set;
} }
/// <summary>
/// The inboxType of this status.
/// </summary>
public string InboxType { public string InboxType {
get; internal set; get; internal set;
} }
private LCQuery query; private LCQuery query;
/// <summary>
/// The data of this status.
/// </summary>
public Dictionary<string, object> Data { public Dictionary<string, object> Data {
get; set; get; set;
} }
/// <summary>
/// Constructs a LCStatus.
/// </summary>
public LCStatus() : base(CLASS_NAME) { public LCStatus() : base(CLASS_NAME) {
InboxType = InboxTypeDefault; InboxType = InboxTypeDefault;
Data = new Dictionary<string, object>(); Data = new Dictionary<string, object>();
} }
/// <summary>
/// Sends the status to the followers of this user.
/// </summary>
/// <param name="status"></param>
/// <returns></returns>
public static async Task<LCStatus> SendToFollowers(LCStatus status) { public static async Task<LCStatus> SendToFollowers(LCStatus status) {
if (status == null) { if (status == null) {
throw new ArgumentNullException(nameof(status)); throw new ArgumentNullException(nameof(status));
@ -62,6 +82,12 @@ namespace LeanCloud.Storage {
return await status.Send(); return await status.Send();
} }
/// <summary>
/// Sends the status to the user with targetId in private.
/// </summary>
/// <param name="status"></param>
/// <param name="targetId"></param>
/// <returns></returns>
public static async Task<LCStatus> SendPrivately(LCStatus status, string targetId) { public static async Task<LCStatus> SendPrivately(LCStatus status, string targetId) {
if (status == null) { if (status == null) {
throw new ArgumentNullException(nameof(status)); throw new ArgumentNullException(nameof(status));
@ -84,6 +110,10 @@ namespace LeanCloud.Storage {
return await status.Send(); return await status.Send();
} }
/// <summary>
/// Sends this status.
/// </summary>
/// <returns></returns>
public async Task<LCStatus> Send() { public async Task<LCStatus> Send() {
LCUser user = await LCUser.GetCurrent(); LCUser user = await LCUser.GetCurrent();
if (user == null) { if (user == null) {
@ -118,6 +148,10 @@ namespace LeanCloud.Storage {
return this; return this;
} }
/// <summary>
/// Deletes this status.
/// </summary>
/// <returns></returns>
public new async Task Delete() { public new async Task Delete() {
LCUser user = await LCUser.GetCurrent(); LCUser user = await LCUser.GetCurrent();
if (user == null) { if (user == null) {
@ -137,6 +171,11 @@ namespace LeanCloud.Storage {
} }
} }
/// <summary>
/// Gets the count of the status with inboxType.
/// </summary>
/// <param name="inboxType"></param>
/// <returns></returns>
public static async Task<LCStatusCount> GetCount(string inboxType) { public static async Task<LCStatusCount> GetCount(string inboxType) {
LCUser user = await LCUser.GetCurrent(); LCUser user = await LCUser.GetCurrent();
if (user == null) { if (user == null) {
@ -158,6 +197,11 @@ namespace LeanCloud.Storage {
return statusCount; return statusCount;
} }
/// <summary>
/// Resets the count of the status to be zero.
/// </summary>
/// <param name="inboxType"></param>
/// <returns></returns>
public static async Task ResetUnreadCount(string inboxType = null) { public static async Task ResetUnreadCount(string inboxType = null) {
LCUser user = await LCUser.GetCurrent(); LCUser user = await LCUser.GetCurrent();
if (user == null) { if (user == null) {

View File

@ -1,9 +1,18 @@
namespace LeanCloud.Storage { namespace LeanCloud.Storage {
/// <summary>
/// LCStatusCount is a result that contains the count of status.
/// </summary>
public class LCStatusCount { public class LCStatusCount {
/// <summary>
/// The total count.
/// </summary>
public int Total { public int Total {
get; set; get; set;
} }
/// <summary>
/// The unread count.
/// </summary>
public int Unread { public int Unread {
get; set; get; set;
} }

View File

@ -9,25 +9,45 @@ using LeanCloud.Storage.Internal.Codec;
using LeanCloud.Storage.Internal.Object; using LeanCloud.Storage.Internal.Object;
namespace LeanCloud.Storage { namespace LeanCloud.Storage {
/// <summary>
/// LCStatusQuery is the query of LCStatus.
/// </summary>
public class LCStatusQuery : LCQuery<LCStatus> { public class LCStatusQuery : LCQuery<LCStatus> {
/// <summary>
/// The inbox type for query.
/// </summary>
public string InboxType { public string InboxType {
get; set; get; set;
} }
/// <summary>
/// The since id for the query.
/// </summary>
public int SinceId { public int SinceId {
get; set; get; set;
} }
/// <summary>
/// The max id for the query.
/// </summary>
public int MaxId { public int MaxId {
get; set; get; set;
} }
/// <summary>
/// Constructs a LCStatusQuery with inboxType.
/// </summary>
/// <param name="inboxType"></param>
public LCStatusQuery(string inboxType = LCStatus.InboxTypeDefault) : base("_Status") { public LCStatusQuery(string inboxType = LCStatus.InboxTypeDefault) : base("_Status") {
InboxType = inboxType; InboxType = inboxType;
SinceId = 0; SinceId = 0;
MaxId = 0; MaxId = 0;
} }
/// <summary>
/// Retrieves a list of LCStatus that satisfy the query from the cloud.
/// </summary>
/// <returns></returns>
public new async Task<ReadOnlyCollection<LCStatus>> Find() { public new async Task<ReadOnlyCollection<LCStatus>> Find() {
LCUser user = await LCUser.GetCurrent(); LCUser user = await LCUser.GetCurrent();
if (user == null) { if (user == null) {

View File

@ -6,6 +6,9 @@ using LeanCloud.Common;
using LeanCloud.Storage.Internal.Object; using LeanCloud.Storage.Internal.Object;
namespace LeanCloud.Storage { namespace LeanCloud.Storage {
/// <summary>
/// LCUser represents a user for a LeanCloud application.
/// </summary>
public class LCUser : LCObject { public class LCUser : LCObject {
public const string CLASS_NAME = "_User"; public const string CLASS_NAME = "_User";
@ -79,6 +82,11 @@ namespace LeanCloud.Storage {
static LCUser currentUser; static LCUser currentUser;
/// <summary>
/// Gets the currently logged in LCUser with a valid session, from
/// memory or disk if necessary.
/// </summary>
/// <returns></returns>
public static async Task<LCUser> GetCurrent() { public static async Task<LCUser> GetCurrent() {
if (currentUser != null) { if (currentUser != null) {
return currentUser; return currentUser;
@ -700,6 +708,13 @@ namespace LeanCloud.Storage {
.Include("followee"); .Include("followee");
} }
/// <summary>
/// Gets the followers and followees of the currently logged in user.
/// </summary>
/// <param name="includeFollower"></param>
/// <param name="includeFollowee"></param>
/// <param name="returnCount"></param>
/// <returns></returns>
public async Task<LCFollowersAndFollowees> GetFollowersAndFollowees(bool includeFollower = false, public async Task<LCFollowersAndFollowees> GetFollowersAndFollowees(bool includeFollower = false,
bool includeFollowee = false, bool returnCount = false) { bool includeFollowee = false, bool returnCount = false) {
Dictionary<string, object> queryParams = new Dictionary<string, object>(); Dictionary<string, object> queryParams = new Dictionary<string, object>();

View File

@ -26,35 +26,68 @@ namespace LeanCloud.Storage {
Month Month
} }
/// <summary>
/// LCLeaderboard represents LeanCloud leaderboard and contains static functions
/// that handle the statistic.
/// </summary>
public class LCLeaderboard { public class LCLeaderboard {
/// <summary>
/// The name of statistic.
/// </summary>
public string StatisticName { public string StatisticName {
get; private set; get; private set;
} }
/// <summary>
/// The order of this leaderboard.
/// </summary>
public LCLeaderboardOrder Order { public LCLeaderboardOrder Order {
get; private set; get; private set;
} }
/// <summary>
/// The update strategy of this leaderboard.
/// </summary>
public LCLeaderboardUpdateStrategy UpdateStrategy { public LCLeaderboardUpdateStrategy UpdateStrategy {
get; private set; get; private set;
} }
/// <summary>
/// The interval of the version that the leaderboard resets.
/// </summary>
public LCLeaderboardVersionChangeInterval VersionChangeInterval { public LCLeaderboardVersionChangeInterval VersionChangeInterval {
get; private set; get; private set;
} }
/// <summary>
/// The version of this leaderboard.
/// </summary>
public int Version { public int Version {
get; private set; get; private set;
} }
/// <summary>
/// The next time that the leaderboard resets.
/// </summary>
public DateTime NextResetAt { public DateTime NextResetAt {
get; private set; get; private set;
} }
/// <summary>
/// The time that the leaderboard created.
/// </summary>
public DateTime CreatedAt { public DateTime CreatedAt {
get; private set; get; private set;
} }
/// <summary>
/// Creates a LCLeaderboard with a statistic name.
/// </summary>
/// <param name="statisticName"></param>
/// <param name="order"></param>
/// <param name="updateStrategy"></param>
/// <param name="versionChangeInterval"></param>
/// <returns></returns>
public static async Task<LCLeaderboard> CreateLeaderboard(string statisticName, public static async Task<LCLeaderboard> CreateLeaderboard(string statisticName,
LCLeaderboardOrder order = LCLeaderboardOrder.Descending, LCLeaderboardOrder order = LCLeaderboardOrder.Descending,
LCLeaderboardUpdateStrategy updateStrategy = LCLeaderboardUpdateStrategy.Better, LCLeaderboardUpdateStrategy updateStrategy = LCLeaderboardUpdateStrategy.Better,
@ -90,12 +123,23 @@ namespace LeanCloud.Storage {
}; };
} }
/// <summary>
/// Gets the LCLeaderboard with the given name.
/// </summary>
/// <param name="statisticName"></param>
/// <returns></returns>
public static Task<LCLeaderboard> GetLeaderboard(string statisticName) { public static Task<LCLeaderboard> GetLeaderboard(string statisticName) {
LCLeaderboard leaderboard = CreateWithoutData(statisticName); LCLeaderboard leaderboard = CreateWithoutData(statisticName);
return leaderboard.Fetch(); return leaderboard.Fetch();
} }
/// <summary>
/// Updates the statistic of the user.
/// </summary>
/// <param name="user"></param>
/// <param name="statistics"></param>
/// <param name="overwrite"></param>
/// <returns></returns>
public static async Task<ReadOnlyCollection<LCStatistic>> UpdateStatistics(LCUser user, public static async Task<ReadOnlyCollection<LCStatistic>> UpdateStatistics(LCUser user,
Dictionary<string, double> statistics, Dictionary<string, double> statistics,
bool overwrite = false) { bool overwrite = false) {
@ -127,7 +171,12 @@ namespace LeanCloud.Storage {
return null; return null;
} }
/// <summary>
/// Gets the statistics of the user.
/// </summary>
/// <param name="user"></param>
/// <param name="statisticNames"></param>
/// <returns></returns>
public static async Task<ReadOnlyCollection<LCStatistic>> GetStatistics(LCUser user, public static async Task<ReadOnlyCollection<LCStatistic>> GetStatistics(LCUser user,
IEnumerable<string> statisticNames = null) { IEnumerable<string> statisticNames = null) {
if (user == null) { if (user == null) {
@ -151,7 +200,12 @@ namespace LeanCloud.Storage {
return null; return null;
} }
/// <summary>
/// Deletes the statistics of the user with the given name.
/// </summary>
/// <param name="user"></param>
/// <param name="statisticNames"></param>
/// <returns></returns>
public static async Task DeleteStatistics(LCUser user, public static async Task DeleteStatistics(LCUser user,
IEnumerable<string> statisticNames) { IEnumerable<string> statisticNames) {
if (user == null) { if (user == null) {
@ -195,7 +249,15 @@ namespace LeanCloud.Storage {
return null; return null;
} }
/// <summary>
/// Gets the rankings.
/// </summary>
/// <param name="version"></param>
/// <param name="skip"></param>
/// <param name="limit"></param>
/// <param name="selectUserKeys"></param>
/// <param name="includeStatistics"></param>
/// <returns></returns>
public Task<ReadOnlyCollection<LCRanking>> GetResults(int version = -1, public Task<ReadOnlyCollection<LCRanking>> GetResults(int version = -1,
int skip = 0, int skip = 0,
int limit = 10, int limit = 10,
@ -204,7 +266,15 @@ namespace LeanCloud.Storage {
return GetResults(null, version, skip, limit, selectUserKeys, includeStatistics); return GetResults(null, version, skip, limit, selectUserKeys, includeStatistics);
} }
/// <summary>
/// Get the rankings that around the currently logged in user.
/// </summary>
/// <param name="version"></param>
/// <param name="skip"></param>
/// <param name="limit"></param>
/// <param name="selectUserKeys"></param>
/// <param name="includeStatistics"></param>
/// <returns></returns>
public async Task<ReadOnlyCollection<LCRanking>> GetResultsAroundUser(int version = -1, public async Task<ReadOnlyCollection<LCRanking>> GetResultsAroundUser(int version = -1,
int skip = 0, int skip = 0,
int limit = 10, int limit = 10,
@ -214,6 +284,16 @@ namespace LeanCloud.Storage {
return await GetResults(user, version, skip, limit, selectUserKeys, includeStatistics); return await GetResults(user, version, skip, limit, selectUserKeys, includeStatistics);
} }
/// <summary>
/// Gets the rankings of the user.
/// </summary>
/// <param name="user"></param>
/// <param name="version"></param>
/// <param name="skip"></param>
/// <param name="limit"></param>
/// <param name="selectUserKeys"></param>
/// <param name="includeStatistics"></param>
/// <returns></returns>
private async Task<ReadOnlyCollection<LCRanking>> GetResults(LCUser user, private async Task<ReadOnlyCollection<LCRanking>> GetResults(LCUser user,
int version, int version,
int skip, int skip,
@ -249,7 +329,11 @@ namespace LeanCloud.Storage {
return null; return null;
} }
/// <summary>
/// Updates the update strategy of this LCLeaderboard.
/// </summary>
/// <param name="updateStrategy"></param>
/// <returns></returns>
public async Task<LCLeaderboard> UpdateUpdateStrategy(LCLeaderboardUpdateStrategy updateStrategy) { public async Task<LCLeaderboard> UpdateUpdateStrategy(LCLeaderboardUpdateStrategy updateStrategy) {
Dictionary<string, object> data = new Dictionary<string, object> { Dictionary<string, object> data = new Dictionary<string, object> {
{ "updateStrategy", updateStrategy.ToString().ToLower() } { "updateStrategy", updateStrategy.ToString().ToLower() }
@ -264,7 +348,11 @@ namespace LeanCloud.Storage {
return this; return this;
} }
/// <summary>
/// Updates the interval of the version that this LCLeaderboard changes.
/// </summary>
/// <param name="versionChangeInterval"></param>
/// <returns></returns>
public async Task<LCLeaderboard> UpdateVersionChangeInterval(LCLeaderboardVersionChangeInterval versionChangeInterval) { public async Task<LCLeaderboard> UpdateVersionChangeInterval(LCLeaderboardVersionChangeInterval versionChangeInterval) {
Dictionary<string, object> data = new Dictionary<string, object> { Dictionary<string, object> data = new Dictionary<string, object> {
{ "versionChangeInterval", versionChangeInterval.ToString().ToLower() } { "versionChangeInterval", versionChangeInterval.ToString().ToLower() }

View File

@ -4,19 +4,34 @@ using System.Collections.ObjectModel;
using LeanCloud.Storage.Internal.Object; using LeanCloud.Storage.Internal.Object;
namespace LeanCloud.Storage { namespace LeanCloud.Storage {
/// <summary>
/// LCRanking represents the rankings of LCLeaderboard.
/// </summary>
public class LCRanking { public class LCRanking {
/// <summary>
/// The ranking.
/// </summary>
public int Rank { public int Rank {
get; private set; get; private set;
} }
/// <summary>
/// The user of this LCRanking.
/// </summary>
public LCUser User { public LCUser User {
get; private set; get; private set;
} }
/// <summary>
/// The statistic name of this LCRanking.
/// </summary>
public string StatisticName { public string StatisticName {
get; private set; get; private set;
} }
/// <summary>
/// The value of this LCRanking.
/// </summary>
public double Value { public double Value {
get; private set; get; private set;
} }

View File

@ -2,15 +2,27 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace LeanCloud.Storage { namespace LeanCloud.Storage {
/// <summary>
/// LCStatistic represents the statistic of LeanCloud leaderboard.
/// </summary>
public class LCStatistic { public class LCStatistic {
/// <summary>
/// The name of this LCStatistic.
/// </summary>
public string Name { public string Name {
get; private set; get; private set;
} }
/// <summary>
/// The value of this LCStatistic.
/// </summary>
public double Value { public double Value {
get; private set; get; private set;
} }
/// <summary>
/// The version of this LCStatistic.
/// </summary>
public int Version { public int Version {
get; internal set; get; internal set;
} }