/// <summary> /// Converts MoBackObject data to a JSON object for storage. /// </summary> /// <returns>A JSON object.</returns> public override SimpleJSONClass GetJSON() { // Construct a child json object, which is the File type. SimpleJSONClass jsonForUploadFile = new SimpleJSONClass(); jsonForUploadFile["__type"] = "File"; jsonForUploadFile["name"] = Name; jsonForUploadFile["url"] = url; // Final json structure to send to server, to create a new row. SimpleJSONClass jsonStructure = new SimpleJSONClass(); // Add the child json. jsonStructure.Add("FileURL", jsonForUploadFile); // Add other values if any. foreach (KeyValuePair <string, object> item in storeValues) { if (item.Key == "objectId" || item.Key == "createdAt" || item.Key == "updatedAt") { continue; // No need to send auto-populated fields as part of JSON message } SimpleJSONNode node = MoBackUtils.MoBackTypedObjectToJSON(item.Value, columnTypeData[item.Key]); jsonStructure.Add(item.Key, node); } return(jsonStructure); }
/// <summary> /// Returns the JSON object. /// </summary> /// <returns>The JSO.</returns> public SimpleJSONClass GetJSON() { SimpleJSONClass jsonObject = new SimpleJSONClass(); jsonObject.Add("__type", "GeoPoint"); jsonObject.Add("lat", Latitude); jsonObject.Add("lon", Longitude); return(jsonObject); }
/// <summary> /// Initializes a new instance of the <see cref="MoBackInternal.MatchingQuery"/> class. /// </summary> /// <param name="column"> A column. </param> /// <param name="value"> An object value. </param> public MatchingQuery(string column, object value) { constraints = new SimpleJSONClass(); MoBackValueType type = MoBackInternal.MoBackUtils.ExtractMobackType(ref value); constraints.Add(column, MoBackInternal.MoBackUtils.MoBackTypedObjectToJSON(value, type)); }
public static MoBackRequest ResetPassword(string userName) { SimpleJSONClass jsonStructure = new SimpleJSONClass(); jsonStructure.Add("userId", userName); byte[] postData = jsonStructure.ToString().ToByteArray(); return(new MoBackRequest(MoBackURLS.ResetPassword, HTTPMethod.POST, null, postData)); }
/// <summary> /// Converts MoBackObject data to a JSON object for storage. /// </summary> /// <returns> A JSON object. </returns> public virtual SimpleJSONClass GetJSON() { SimpleJSONClass jsonStructure = new SimpleJSONClass(); foreach (KeyValuePair <string, object> item in storeValues) { SimpleJSONNode node = MoBackUtils.MoBackTypedObjectToJSON(item.Value, columnTypeData[item.Key]); jsonStructure.Add(item.Key, node); } return(jsonStructure); }
/// <summary> /// Initializes a new instance of the <see cref="MoBackInternal.ComparisonQuery"/> class. /// </summary> /// <param name="column"> A column.</param> /// <param name="value"> An object value. </param> /// <param name="comparisonOperator"> A comparison operator as a string. </param> public ComparisonQuery(string column, object value, string comparisonOperator) { constraints = new SimpleJSONClass(); SimpleJSONClass constraint = new SimpleJSONClass(); MoBackValueType type = MoBackInternal.MoBackUtils.ExtractMobackType(ref value); constraint.Add(comparisonOperator, MoBackInternal.MoBackUtils.MoBackTypedObjectToJSON(value, type)); constraints.Add(column, constraint); }
/// <summary> /// Initializes a new instance of the <see cref="MoBackInternal.CompoundQuery"/> class. /// </summary> /// <param name="compoundOperator"> A compound operator. </param> /// <param name="queriesToCompound"> An array of queries to compound. </param> public CompoundQuery(string compoundOperator, params Query[] queriesToCompound) { constraints = new SimpleJSONClass(); SimpleJSONArray constraintValues = new SimpleJSONArray(); foreach (Query query in queriesToCompound) { constraintValues.Add(query.constraints); } constraints.Add(compoundOperator, constraintValues); }
/// <summary> /// Sends the invitation. /// </summary> /// <returns>A MoBackRequest with a MoBackUser type.</returns> /// <param name="emailAddress">Email address.</param> public MoBackRequest SendInvitation(string emailAddress) { if (string.IsNullOrEmpty(emailAddress)) { Debug.LogError("Invalid email address"); return(null); } SimpleJSONClass jsonStructure = new SimpleJSONClass(); jsonStructure.Add("inviteeId", emailAddress); byte[] postData = jsonStructure.ToString().ToByteArray(); return(new MoBackRequest(MoBackURLS.Invitation, HTTPMethod.POST, null, postData)); }
/// <summary> /// Login the specified userName and password. /// </summary> /// <param name="userName">User name.</param> /// <param name="password">Password.</param> /// <returns>A MoBackRequest with a MoBackUser type.</returns> public MoBackRequest Login() { SimpleJSONClass jsonStructure = new SimpleJSONClass(); jsonStructure.Add("userId", UserName); jsonStructure.Add("password", Password); byte[] postData = jsonStructure.ToString().ToByteArray(); MoBackRequest.ResponseProcessor LoginProcessor = (SimpleJSONNode jsonObject) => { string ssotoken = jsonObject["ssotoken"]; if (string.IsNullOrEmpty(ssotoken)) { IsLoggedIn = false; } else { IsLoggedIn = true; MoBack.MoBackAppSettings.SessionToken = ssotoken; } }; return(new MoBackRequest(LoginProcessor, MoBackURLS.Login, HTTPMethod.POST, null, postData)); }
/// <summary> /// Converts MoBackObject data to a JSON object for storage. /// </summary> /// <returns>A JSON object.</returns> public override SimpleJSONClass GetJSON() { SimpleJSONClass jsonStructure = new SimpleJSONClass(); foreach (KeyValuePair <string, object> item in storeValues) { if (item.Key == "objectId" || item.Key == "createdAt" || item.Key == "updatedAt") { continue; // No need to send auto-populated fields as part of JSON message } SimpleJSONNode node = MoBackUtils.MoBackTypedObjectToJSON(item.Value, columnTypeData[item.Key]); jsonStructure.Add(item.Key, node); } return(jsonStructure); }
/// <summary> /// Initializes a new instance of the <see cref="MoBackInternal.ComparisonQuery"/> class. /// </summary> /// <param name="column"> A column.</param> /// <param name="values"> An array object values. </param> /// <param name="comparisonOperator"> A comparison operator as a string. </param> public ComparisonQuery(string column, object[] values, string comparisonOperator) { constraints = new SimpleJSONClass(); SimpleJSONClass constraint = new SimpleJSONClass(); SimpleJSONArray constraintValues = new SimpleJSONArray(); for (int i = 0; i < values.Length; i++) { object value = values[i]; MoBackValueType type = MoBackInternal.MoBackUtils.ExtractMobackType(ref value); constraintValues.Add(MoBackInternal.MoBackUtils.MoBackTypedObjectToJSON(value, type)); } constraint.Add(comparisonOperator, constraintValues); constraints.Add(column, constraint); }
/// <summary> /// Deletes the column. /// </summary> /// <returns>Returns the status of the request.</returns> /// <param name="columnName">Column name.</param> public MoBackRequest DeleteColumn(string columnName) { SimpleJSONClass columnOp = new SimpleJSONClass(); columnOp.Add("__op", "Delete"); SimpleJSONClass columnDataHolder = new SimpleJSONClass(); columnDataHolder.Add(columnName, columnOp); /* * Sample uri: https://api.moback.com/objectmgr/api/schema/{tableName}/ * Sample Json Request Body: * { * "Over21" : {"__op" : "Delete"} * } */ return(new MoBackRequest(MoBackURLS.TablesSpecial + table.TableName, HTTPMethod.PUT, null, columnDataHolder.ToString().ToByteArray())); }
/// <summary> /// Deletes the multiple ojbects. /// </summary> /// <returns>A MoBackRequest.</returns> /// <param name="objectsToDelete">Objects to delete.</param> public MoBackRequest DeleteMultipleOjbects(List <MoBackRow> objectsToDelete) { string uri = MoBackURLS.BatchDelete + table.TableName; SimpleJSONArray jsonArray = new SimpleJSONArray(); SimpleJSONClass jsonBody = new SimpleJSONClass(); foreach (MoBackRow item in objectsToDelete) { jsonArray.Add(MoBackUtils.MoBackTypedObjectToJSON(item.ObjectId, MoBackValueType.String)); } jsonBody.Add("objectIds", jsonArray); byte[] bytes = jsonBody.ToString().ToByteArray(); MoBackRequest.ResponseProcessor deleteCallBack = (SimpleJSONNode responseJson) => { SimpleJSONArray responseArray = responseJson["deletedObjectIds"].AsArray; Debug.Log(responseArray.ToString()); foreach (SimpleJSONNode item in responseArray) { MoBackRow deletedRow = objectsToDelete.Find(row => row.ObjectId == item.Value); if (deletedRow != null) { deletedRow.ResetMetaData(null); } else { Debug.Log("Can't find row"); } } }; /* * Sample uri: https://api.moback.com/objectmgr/api/collections/batch/delete/{tableName} * Sample Json Request Body: * { * "objectIds" : ["Vp6pfOSwp23tC3IN", "Vp6ZnOSwp23tC3Hv"] * } */ return(new MoBackRequest(deleteCallBack, uri, HTTPMethod.POST, null, bytes)); }
/// <summary> /// Creates the column. /// </summary> /// <returns>Returns the status of the request.</returns> /// <param name="columnName">Column name.</param> /// <param name="columnType">Column type.</param> public MoBackRequest CreateColumn(string columnName, MoBackValueType columnType) { SimpleJSONClass columnTypeSpecifier = new SimpleJSONClass(); // TODO: check if any of these type-names don't fit the moback spec. According to REST api reference they should be... columnTypeSpecifier.Add("__type", columnTypeSpecifier.ToString()); SimpleJSONClass columnDataHolder = new SimpleJSONClass(); columnDataHolder.Add(columnName, columnTypeSpecifier); /* * Sample uri: https://api.moback.com/objectmgr/api/schema/{tableName}/ * Sample Json Request Body: * { * "FavoriteFood" : {"__type" : "string"} * } */ return(new MoBackRequest(MoBackURLS.TablesSpecial + table.TableName, HTTPMethod.PUT, null, columnDataHolder.ToString().ToByteArray())); }
/// <summary> /// Merge queries, potentially recursively. /// </summary> /// <param name="first">First query. This also contains the merged result after the merge.</param> /// <param name="second">Second query.</param> private void MergeQueries(SimpleJSONClass first, SimpleJSONClass second) { // Needs to merge various things correctly. For a (non-encompassing) example of the problem, take: // {"playerName":"Sean Plott","cheatMode":{"thisIsanObject":true}} // {"playerName":{"$exists":true}} // {"cheatMode":{"note":"ThisIsPartOfAnObjectNotAConstraint", "cheat":"noSecretCows"}} // {"rank":{"$gte":1,"$lte":10}} // {"rank":{"$in":[2,3,6]}} // {"$and":[{"StudentName":”Mark Lee”},{"standard":4}]} // Should turn into: // {"playerName":"Sean Plott","cheatMode":{"note":"ThisIsPartOfAnObjectNotAConstraint", "cheat":"noSecretCows"}, "rank":{"$gte":1,"$lte":10,"$in":[2,3,6]}, // "$and":[{"StudentName":”Mark Lee”},{"standard":4}]} // Approach: // 0.When keywords don't conflict, just add both // 1.Two objects containing $keywords should be merged, following these rules recursively (relevantly, constants override constants, but arrays with $names are merged) // 2.Arrays with $names should be merged, by appending second array after first // 3.For two constant values (strings, ints, etc), in the case of a conflict the second value should override the first. // ^Objects not containing $keywords and arrays without $names should be treated as constants // 5.When a conflict is not otherwise covered by these rules, just use the second of the two values // 6.Consider implementing in the future: Between an object containing $keywords and a constant match being provied, pick the constant match // (because an exact match effectively supercedes all constraints (except maybe mutually conflicting constraints which should axiomatically return nothing... // but not sure how that should be dealt with anyway? life would be simpler if we had an $eq operator exposed) foreach (KeyValuePair <string, SimpleJSONNode> node in second.dict) { if (first.dict.ContainsKey(node.Key)) { SimpleJSONNode firstNode = first[node.Key]; SimpleJSONNode secondNode = node.Value; System.Type firstType = firstNode.valueType; System.Type secondType = secondNode.valueType; if (firstType == typeof(SimpleJSONClass) || secondType == typeof(SimpleJSONClass)) { bool firstIsClassContainingKeywords = firstType == typeof(SimpleJSONClass) && JsonClassContainsKeywords((SimpleJSONClass)firstNode); bool secondIsClassContainingKeywords = secondType == typeof(SimpleJSONClass) && JsonClassContainsKeywords((SimpleJSONClass)secondNode); if (firstIsClassContainingKeywords && secondIsClassContainingKeywords) { // Merge recursively SimpleJSONClass firstObject = (SimpleJSONClass)firstNode; SimpleJSONClass secondObject = (SimpleJSONClass)secondNode; MergeQueries(firstObject, secondObject); } else { // Newer value takes precedence first.Add(node.Key, node.Value); } } else if (firstType == typeof(SimpleJSONArray) && secondType == typeof(SimpleJSONArray) && NameIsKeyword(node.Key)) { // Merge arrays SimpleJSONArray firstArray = (SimpleJSONArray)firstNode; SimpleJSONArray secondArray = (SimpleJSONArray)secondNode; for (int i = 0; i < secondArray.Count; i++) { firstArray.Add(secondArray[i]); } } else { // Newer value takes precedence first.Add(node.Key, node.Value); } } else { // No conflict, just add first.Add(node.Key, node.Value); } } }
/// <summary> /// Saves multiple objects with one single call to server. /// </summary> /// <returns>The MobackRequest.</returns> /// <param name="rowsToSave">MoBack Rows need to save.</param> public MoBackRequest SaveMultipleObjects(List <MoBackRow> rowsToSave) { string uri = MoBackURLS.Batch + table.TableName; SimpleJSONArray jsonArray = new SimpleJSONArray(); SimpleJSONClass jsonStructure = new SimpleJSONClass(); for (int i = 0; i < rowsToSave.Count; i++) { SimpleJSONClass jsonToSave = rowsToSave[i].GetJSON(); if (rowsToSave[i].ObjectId != null) { jsonToSave.Add("objectId", rowsToSave[i].ObjectId); } jsonArray.Add(jsonToSave); } jsonStructure.Add("objects", jsonArray); Debug.Log(jsonStructure.ToString()); byte[] bytes = jsonStructure.ToString().ToByteArray(); // Construct a callback to update all rowsToSave. MoBackRequest.ResponseProcessor objUpdater = (SimpleJSONNode responseJson) => { SimpleJSONClass allObjectsInJsonFormat = responseJson["batchResponse"].AsObject; // The response should have the same amount as of the request body. if (allObjectsInJsonFormat.Count != rowsToSave.Count) { Debug.LogError(string.Format("Response objects count: {0}. Request objects count: {1}", allObjectsInJsonFormat.Count, rowsToSave.Count)); Debug.LogError("Response doesn't have the same object as Request Body. Something wrong!"); return; } for (int i = 0; i < rowsToSave.Count; i++) { SimpleJSONClass jsonAtCurrentIndex = allObjectsInJsonFormat[i] as SimpleJSONClass; if (!jsonAtCurrentIndex["success"].AsBool) { Debug.LogError("Unable to save: " + jsonAtCurrentIndex["objectId"]); continue; } if (!string.IsNullOrEmpty(jsonAtCurrentIndex["createdAt"].ToString())) { string objectId = jsonAtCurrentIndex["objectId"]; DateTime createdTime = MoBackDate.DateFromString(jsonAtCurrentIndex["createdAt"]); rowsToSave[i].UpdateAfterSave(objectId, createdTime, createdTime); } else if (!string.IsNullOrEmpty(jsonAtCurrentIndex["updatedAt"].ToString())) { string objectId = jsonAtCurrentIndex["objectId"]; DateTime updateTime = MoBackDate.DateFromString(jsonAtCurrentIndex["updatedAt"]); rowsToSave[i].UpdateAfterSave(objectId, null, updateTime); } } }; /* * Sample uri: https://api.moback.com/objectmgr/api/collections/batch/{tableName} * Sample Json Request Body: * { * "objects" : [{ "Name" : "Joe", "FavoriteFood" : ["pizza", "fried eggs", "ham sandwich"]}] * } */ return(new MoBackRequest(objUpdater, uri, HTTPMethod.POST, null, bytes)); }