/// <summary> /// Update/Insert the specified collection of entities in batches of the specified size, using the specified resource identifier. /// </summary> /// <param name="payload">A collection of entities, where each represents a single row in the target resource.</param> /// <param name="batchSize">The maximum number of entities to process in a single batch.</param> /// <param name="breakFunction">A function which, when evaluated true, causes a batch to be sent (possibly before it reaches <paramref name="batchSize"/>).</param> /// <param name="resourceId">The identifier (4x4) for a resource on the Socrata host to target.</param> /// <returns>A collection of <see cref="SodaResult"/>, one for each batched Upsert.</returns> /// <exception cref="System.ArgumentOutOfRangeException">Thrown if the specified <paramref name="resourceId"/> does not match the Socrata 4x4 pattern.</exception> /// <exception cref="System.InvalidOperationException">Thrown if this SodaClient was initialized without authentication credentials.</exception> public IEnumerable <SodaResult> BatchUpsert <TRow>(IEnumerable <TRow> payload, int batchSize, Func <IEnumerable <TRow>, TRow, bool> breakFunction, string resourceId) where TRow : class { if (FourByFour.IsNotValid(resourceId)) { throw new ArgumentOutOfRangeException("resourceId", "The provided resourceId is not a valid Socrata (4x4) resource identifier."); } if (String.IsNullOrEmpty(Username) || String.IsNullOrEmpty(password)) { throw new InvalidOperationException("Write operations require an authenticated client."); } Queue <TRow> queue = new Queue <TRow>(payload); while (queue.Any()) { //make the next batch to send var batch = new List <TRow>(); for (var index = 0; index < batchSize && queue.Count > 0; index++) { //if we have a break function that returns true => bail out early if (breakFunction != null && breakFunction(batch, queue.Peek())) { break; } //otherwise add the next item in queue to this batch batch.Add(queue.Dequeue()); } //now send this batch SodaResult result; try { result = Upsert <TRow>(batch, resourceId); } catch (WebException webException) { string message = webException.UnwrapExceptionMessage(); result = new SodaResult() { Message = webException.Message, IsError = true, ErrorCode = message, Data = payload }; } catch (Exception ex) { result = new SodaResult() { Message = ex.Message, IsError = true, ErrorCode = ex.Message, Data = payload }; } //yield return here creates an iterator - results aren't returned until explicitly requested via foreach //or similar interation on the result of the call to BatchUpsert. yield return(result); } }
/// <summary> /// Replace any existing rows with the payload data, using the specified resource identifier. /// </summary> /// <param name="payload">A string of serialized data.</param> /// <param name="dataFormat">One of the data-interchange formats that Socrata supports, into which the payload has been serialized.</param> /// <param name="resourceId">The identifier (4x4) for a resource on the Socrata host to target.</param> /// <returns>A <see cref="SodaResult"/> indicating success or failure.</returns> /// <exception cref="System.ArgumentOutOfRangeException">Thrown if the specified <paramref name="dataFormat"/> is equal to <see cref="SodaDataFormat.XML"/>.</exception> /// <exception cref="System.ArgumentOutOfRangeException">Thrown if the specified <paramref name="resourceId"/> does not match the Socrata 4x4 pattern.</exception> /// <exception cref="System.InvalidOperationException">Thrown if this SodaClient was initialized without authentication credentials.</exception> public SodaResult Replace(string payload, SodaDataFormat dataFormat, string resourceId) { if (dataFormat == SodaDataFormat.XML) { throw new ArgumentOutOfRangeException("dataFormat", "XML is not a valid format for write operations."); } if (FourByFour.IsNotValid(resourceId)) { throw new ArgumentOutOfRangeException("resourceId", "The provided resourceId is not a valid Socrata (4x4) resource identifier."); } if (String.IsNullOrEmpty(Username) || String.IsNullOrEmpty(password)) { throw new InvalidOperationException("Write operations require an authenticated client."); } var uri = SodaUri.ForResourceAPI(Host, resourceId); var request = new SodaRequest(uri, "PUT", AppToken, Username, password, dataFormat, payload); SodaResult result = null; try { if (dataFormat == SodaDataFormat.JSON) { result = request.ParseResponse <SodaResult>(); } else if (dataFormat == SodaDataFormat.CSV) { string resultJson = request.ParseResponse <string>(); result = Newtonsoft.Json.JsonConvert.DeserializeObject <SodaResult>(resultJson); } } catch (WebException webException) { string message = webException.UnwrapExceptionMessage(); result = new SodaResult() { Message = webException.Message, IsError = true, ErrorCode = message, Data = payload }; } catch (Exception ex) { result = new SodaResult() { Message = ex.Message, IsError = true, ErrorCode = ex.Message, Data = payload }; } return(result); }
/// <summary> /// Updates this ResourceMetadata on the Socrata Host. /// </summary> /// <returns>A SodaResult, indicating success or failure.</returns> public SodaResult Update() { var metadataUri = SodaUri.ForMetadata(Host, Identifier); SodaResult result = new SodaResult(); try { //use PUT to replace all existing metadata with the new values result = Client.write <ResourceMetadata, SodaResult>(metadataUri, "PUT", this); //no exception thrown => success! result.IsError = false; result.Message = String.Format("Metadata for {0} updated successfully.", Identifier); } catch (Exception ex) { result.IsError = true; result.Message = ex.Message; result.Data = ex.StackTrace; } return(result); }
/// <summary> /// Updates this ResourceMetadata on the Socrata Host. /// </summary> /// <returns>A SodaResult, indicating success or failure.</returns> public SodaResult Update() { var metadataUri = SodaUri.ForMetadata(Host, Identifier); SodaResult result = new SodaResult(); try { //use PUT to replace all existing metadata with the new values result = Client.write<ResourceMetadata, SodaResult>(metadataUri, "PUT", this); //no exception thrown => success! result.IsError = false; result.Message = String.Format("Metadata for {0} updated successfully.", Identifier); } catch (Exception ex) { result.IsError = true; result.Message = ex.Message; result.Data = ex.StackTrace; } return result; }