Permalink
Browse files

Refactored ODataTable class to simplify adding batch support.

  • Loading branch information...
1 parent d44b485 commit 0df83f8f316fe2a6a97b28ae9b925a5e29b084e5 @object object committed Aug 25, 2012
View
@@ -1,4 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
+ <mm-GraphProvider>BUILTINDARK</mm-GraphProvider>
+ <StartPaused>true</StartPaused>
<BuildExecutable>C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe</BuildExecutable>
</configuration>
@@ -0,0 +1,78 @@
+using System;
+using System.Net;
+using System.Text;
+using Simple.NExtLib;
+using Simple.OData;
+
+namespace Simple.Data.OData
+{
+ public class BatchRequestBuilder : RequestBuilder
+ {
+ private string _batchId;
+ private string _changesetId;
+ private StringBuilder _contentBuilder;
+
+ public BatchRequestBuilder(string urlBase)
+ : base(urlBase)
+ {
+ }
+
+ public void BeginBatch(string command, string method, string content = null)
+ {
+ var uri = CreateRequestUrl(command);
+ this.Request = (HttpWebRequest)WebRequest.Create(uri);
+ this.Request.Method = RestVerbs.POST;
+ _batchId = Guid.NewGuid().ToString();
+ this.Request.ContentType = "multipart/mixed; boundary=" + _batchId;
+ _contentBuilder = new StringBuilder();
+ }
+
+ public void EndBatch()
+ {
+ _contentBuilder.AppendLine(string.Format("--batch({0})--", _batchId));
+ AddContent(this.Request, _contentBuilder.ToString());
+ }
+
+ public override void AddTableCommand(string command, string method, string content = null)
+ {
+ _contentBuilder.AppendLine(string.Format("--batch_{0}", _batchId));
+ if (method == RestVerbs.GET)
+ {
+ if (_changesetId != null)
+ {
+ _contentBuilder.AppendLine(string.Format("--changeset_{0}--", _changesetId));
+ _contentBuilder.AppendLine();
+ }
+ _changesetId = null;
+ }
+ else
+ {
+ if (_changesetId == null)
+ {
+ _changesetId = Guid.NewGuid().ToString();
+ _contentBuilder.AppendLine(string.Format("Content-Type: multipart/mixed; boundary=changeset_{0}", _changesetId));
+ _contentBuilder.AppendLine(string.Format("Content-Length: {0}", 0));
+ _contentBuilder.AppendLine();
+ _contentBuilder.AppendLine(string.Format("--changeset_{0}", _changesetId));
+ }
+ }
+ _contentBuilder.AppendLine("Content-Type: application/http");
+ _contentBuilder.AppendLine("Content-Transfer-Encoding:binary");
+ _contentBuilder.AppendLine();
+ _contentBuilder.AppendLine(string.Format("{0} {1} HTTP/{2}", method, command, "1.1"));
+ _contentBuilder.AppendLine(this.Host);
+
+ if (content != null)
+ {
+ _contentBuilder.AppendLine(string.Format("Content-Type: application/atom+xml;type=entry"));
+ _contentBuilder.AppendLine(string.Format("Content-Length: {0}", (content ?? string.Empty).Length));
+ _contentBuilder.Append(content);
+ }
+ }
+
+ protected override void AddContent(WebRequest request, string content)
+ {
+ _contentBuilder.AppendLine(content);
+ }
+ }
+}
@@ -0,0 +1,46 @@
+using System.Net;
+using Simple.NExtLib;
+using Simple.OData;
+
+namespace Simple.Data.OData
+{
+ public class CommandRequestBuilder : RequestBuilder
+ {
+ public CommandRequestBuilder(string urlBase)
+ : base(urlBase)
+ {
+ }
+
+ public override void AddTableCommand(string command, string method, string content = null)
+ {
+ this.Request = CreateTableRequest(command, method, content);
+ }
+
+ protected override void AddContent(WebRequest request, string content)
+ {
+ request.ContentType = "application/atom+xml";
+ request.SetContent(content);
+ }
+
+ private HttpWebRequest CreateTableRequest(string command, string method, string content = null)
+ {
+ var uri = CreateRequestUrl(command);
+ var request = (HttpWebRequest)WebRequest.Create(uri);
+ request.Method = method;
+ request.ContentLength = (content ?? string.Empty).Length;
+
+ // TODO: revise
+ //if (method == "PUT" || method == "DELETE" || method == "MERGE")
+ //{
+ // request.Headers.Add("If-Match", "*");
+ //}
+
+ if (content != null)
+ {
+ AddContent(request, content);
+ }
+
+ return request;
+ }
+ }
+}
@@ -0,0 +1,8 @@
+using Simple.OData;
+
+namespace Simple.Data.OData
+{
+ public class CommandRequestRunner : RequestRunner
+ {
+ }
+}
@@ -2,18 +2,32 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
+using Simple.OData;
namespace Simple.Data.OData
{
class ODataAdapterTransaction : IAdapterTransaction
{
+ class AdapterRequest
+ {
+ public string MethodName { get; private set; }
+ public object[] Parameters { get; private set; }
+
+ public AdapterRequest(string methodName, params object[] parameters)
+ {
+ this.MethodName = methodName;
+ this.Parameters = parameters;
+ }
+ }
+
private readonly ODataTableAdapter _adapter;
- private List<Tuple<string, object[]>> _calls;
+ private List<AdapterRequest> _requests;
public ODataAdapterTransaction(ODataTableAdapter adapter)
{
_adapter = adapter;
- _calls = new List<Tuple<string, object[]>>();
+ _adapter.SetRequestHandlers(new BatchRequestBuilder(_adapter.UrlBase), new RequestRunner());
+ _requests = new List<AdapterRequest>();
}
public string Name
@@ -23,54 +37,25 @@ public string Name
public void Commit()
{
- foreach (var call in _calls)
- {
- switch (call.Item1)
- {
- case "Delete":
- _adapter.Delete((string)call.Item2[0], (SimpleExpression)call.Item2[1]);
- break;
- case "Insert":
- _adapter.Insert((string)call.Item2[0], (IDictionary<string, object>)call.Item2[1], (bool)call.Item2[2]);
- break;
- case "InsertMany":
- _adapter.InsertMany((string)call.Item2[0], (IEnumerable<IDictionary<string, object>>)call.Item2[1], (Func<IDictionary<string, object>, Exception, bool>)call.Item2[2], (bool)call.Item2[3]);
- break;
- case "Update":
- _adapter.Update((string)call.Item2[0], (IDictionary<string, object>)call.Item2[1], (SimpleExpression)call.Item2[2]);
- break;
- case "UpdateMany":
- switch (call.Item2.Length)
- {
- case 2:
- _adapter.UpdateMany((string)call.Item2[0], (IEnumerable<IDictionary<string, object>>)call.Item2[1]);
- break;
- case 3:
- if (call.Item2[1] is IList<IDictionary<string, object>>)
- _adapter.UpdateMany((string)call.Item2[0], (IList<IDictionary<string, object>>)call.Item2[1], (IEnumerable<string>)call.Item2[2]);
- else
- _adapter.UpdateMany((string)call.Item2[0], (IEnumerable<IDictionary<string, object>>)call.Item2[1], (IList<string>)call.Item2[2]);
- break;
- }
- break;
- }
- }
- _calls.Clear();
+ SendBatchRequest();
+ _adapter.SetRequestHandlers(new CommandRequestBuilder(_adapter.UrlBase), new RequestRunner());
+ _requests.Clear();
}
public void Rollback()
{
- _calls.Clear();
+ _adapter.SetRequestHandlers(new CommandRequestBuilder(_adapter.UrlBase), new RequestRunner());
+ _requests.Clear();
}
public void Dispose()
{
- _calls.Clear();
+ _requests.Clear();
}
public int Delete(string tableName, SimpleExpression criteria)
{
- _calls.Add(new Tuple<string, object[]>("Delete", new object[] { tableName, criteria }));
+ _requests.Add(new AdapterRequest("Delete", tableName, criteria ));
return 0;
}
@@ -86,13 +71,13 @@ public int Delete(string tableName, SimpleExpression criteria)
public IDictionary<string, object> Insert(string tableName, IDictionary<string, object> data, bool resultRequired)
{
- _calls.Add(new Tuple<string, object[]>("Insert", new object[] { tableName, data, resultRequired }));
+ _requests.Add(new AdapterRequest("Insert", tableName, data, resultRequired ));
return null;
}
public IEnumerable<IDictionary<string, object>> InsertMany(string tableName, IEnumerable<IDictionary<string, object>> data, Func<IDictionary<string, object>, Exception, bool> onError, bool resultRequired)
{
- _calls.Add(new Tuple<string, object[]>("InsertMany", new object[] { tableName, data, onError, resultRequired }));
+ _requests.Add(new AdapterRequest("InsertMany", tableName, data, onError, resultRequired ));
return null;
}
@@ -103,26 +88,65 @@ public int Delete(string tableName, SimpleExpression criteria)
public int Update(string tableName, IDictionary<string, object> data, SimpleExpression criteria)
{
- _calls.Add(new Tuple<string, object[]>("Update", new object[] { tableName, data, criteria }));
+ _requests.Add(new AdapterRequest("Update", tableName, data, criteria ));
return 0;
}
public int UpdateMany(string tableName, IList<IDictionary<string, object>> dataList, IEnumerable<string> criteriaFieldNames)
{
- _calls.Add(new Tuple<string, object[]>("UpdateMany", new object[] { tableName, dataList, criteriaFieldNames }));
+ _requests.Add(new AdapterRequest("UpdateMany1", tableName, dataList, criteriaFieldNames ));
return 0;
}
public int UpdateMany(string tableName, IEnumerable<IDictionary<string, object>> dataList, IList<string> keyFields)
{
- _calls.Add(new Tuple<string, object[]>("UpdateMany", new object[] { tableName, dataList, keyFields }));
+ _requests.Add(new AdapterRequest("UpdateMany2", tableName, dataList, keyFields ));
return 0;
}
public int UpdateMany(string tableName, IEnumerable<IDictionary<string, object>> dataList)
{
- _calls.Add(new Tuple<string, object[]>("UpdateMany", new object[] { tableName, dataList }));
+ _requests.Add(new AdapterRequest("UpdateMany3", tableName, dataList ));
return 0;
}
+
+ private void SendBatchRequest()
+ {
+ foreach (var request in _requests)
+ {
+ var tableName = (string)request.Parameters[0];
+ switch (request.MethodName)
+ {
+ case "Delete":
+ _adapter.Delete(tableName,
+ (SimpleExpression)request.Parameters[1]);
+ break;
+ case "Insert":
+ _adapter.Insert(tableName,
+ (IDictionary<string, object>)request.Parameters[1], (bool)request.Parameters[2]);
+ break;
+ case "InsertMany":
+ _adapter.InsertMany(tableName,
+ (IEnumerable<IDictionary<string, object>>)request.Parameters[1], (Func<IDictionary<string, object>, Exception, bool>)request.Parameters[2], (bool)request.Parameters[3]);
+ break;
+ case "Update":
+ _adapter.Update(tableName,
+ (IDictionary<string, object>)request.Parameters[1], (SimpleExpression)request.Parameters[2]);
+ break;
+ case "UpdateMany1":
+ _adapter.UpdateMany(tableName,
+ (IList<IDictionary<string, object>>)request.Parameters[1], (IEnumerable<string>)request.Parameters[2]);
+ break;
+ case "UpdateMany2":
+ _adapter.UpdateMany(tableName,
+ (IEnumerable<IDictionary<string, object>>)request.Parameters[1], (IList<string>)request.Parameters[2]);
+ break;
+ case "UpdateMany3":
+ _adapter.UpdateMany(tableName,
+ (IEnumerable<IDictionary<string, object>>)request.Parameters[1]);
+ break;
+ }
+ }
+ }
}
}
Oops, something went wrong.

0 comments on commit 0df83f8

Please sign in to comment.