Skip to content

Commit

Permalink
Refactored and added more tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
object committed Sep 26, 2012
1 parent 9bb2261 commit 8ad5a1f
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 45 deletions.
43 changes: 43 additions & 0 deletions Simple.Data.OData.IntegrationTests/UpdateTest.cs
Expand Up @@ -25,6 +25,20 @@ public void UpdateObject()
Assert.Equal(123m, product.UnitPrice);
}

[Fact]
public void AddSingleAssociation()
{
var category = _db.Categories.Insert(CategoryName: "Test1");
var product = _db.Products.Insert(ProductName: "Test2", UnitPrice: 18m);

_db.Products.UpdateByProductName(ProductName: "Test2", Category: category);

product = _db.Products.FindByProductName("Test2");
Assert.Equal(category.CategoryID, product.CategoryID);
category = _db.Category.WithProducts().FindByCategoryName("Test1");
Assert.True(category.Products.Count == 1);
}

[Fact]
public void UpdateSingleAssociation()
{
Expand All @@ -39,6 +53,35 @@ public void UpdateSingleAssociation()
Assert.True(category.Products.Count == 1);
}

[Fact]
public void RemoveSingleAssociation()
{
var category = _db.Categories.Insert(CategoryName: "Test6");
var product = _db.Products.Insert(ProductName: "Test7", UnitPrice: 18m, Category: category);
product = _db.Products.FindByProductName("Test7");
_db.Products.UpdateByProductName(ProductName: "Test7", Category: category);
product = _db.Products.FindByProductName("Test7");
Assert.Equal(category.CategoryID, product.CategoryID);

_db.Products.UpdateByProductName(ProductName: "Test7", Category: null);

product = _db.Products.FindByProductName("Test7");
Assert.Equal(0, product.CategoryID);
}

[Fact]
public void UpdateFieldsAndAssociation()
{
var category = _db.Categories.Insert(CategoryName: "Test1");
var product = _db.Products.Insert(ProductName: "Test2", UnitPrice: 18m, CategoryID: 1);

_db.Products.UpdateByProductName(ProductName: "Test2", UnitPrice: 19m, Category: category);

product = _db.Products.FindByProductName("Test2");
Assert.Equal(19m, product.UnitPrice);
Assert.Equal(category.CategoryID, product.CategoryID);
}

[Fact]
public void UpdateMultipleAssociations()
{
Expand Down
29 changes: 2 additions & 27 deletions Simple.Data.OData/ODataTableAdapter.cs
Expand Up @@ -127,48 +127,23 @@ public override bool IsExpressionFunction(string functionName, params object[] a

private int UpdateByExpression(string tableName, IDictionary<string, object> data, SimpleExpression criteria, IAdapterTransaction transaction)
{
// TODO: optimize
string[] keyFieldNames = GetSchema().FindTable(tableName).PrimaryKey.AsEnumerable().ToArray();
var entries = FindByExpression(tableName, criteria);

foreach (var entry in entries)
{
var namedKeyValues = new Dictionary<string, object>();
for (int index = 0; index < keyFieldNames.Count(); index++)
{
namedKeyValues.Add(keyFieldNames[index], entry[keyFieldNames[index]]);
}
var formattedKeyValues = _expressionFormatter.Format(namedKeyValues);
bool merge = false;
foreach (var item in entry)
{
if (!keyFieldNames.Contains(item.Key) && !data.ContainsKey(item.Key))
{
merge = true;
break;
}
}
new RequestExecutor(_urlBase, _schema, transaction).UpdateEntry(tableName, formattedKeyValues, data, merge, transaction);
new RequestExecutor(_urlBase, _schema, transaction).UpdateEntry(tableName, entry, data, transaction);
}
// TODO: what to return?
return 0;
}

private int DeleteByExpression(string tableName, SimpleExpression criteria, IAdapterTransaction transaction)
{
// TODO: optimize
string[] keyFieldNames = GetSchema().FindTable(tableName).PrimaryKey.AsEnumerable().ToArray();
var entries = FindByExpression(tableName, criteria);

foreach (var entry in entries)
{
var namedKeyValues = new Dictionary<string, object>();
for (int index = 0; index < keyFieldNames.Count(); index++)
{
namedKeyValues.Add(keyFieldNames[index], entry[keyFieldNames[index]]);
}
var formattedKeyValues = _expressionFormatter.Format(namedKeyValues);
new RequestExecutor(_urlBase, _schema, transaction).DeleteEntry(tableName, formattedKeyValues, transaction);
new RequestExecutor(_urlBase, _schema, transaction).DeleteEntry(tableName, entry, transaction);
}
// TODO: what to return?
return 0;
Expand Down
64 changes: 46 additions & 18 deletions Simple.Data.OData/RequestExecutor.cs
Expand Up @@ -39,6 +39,7 @@ internal class RequestExecutor
private DatabaseSchema _schema;
private RequestBuilder _requestBuilder;
private RequestRunner _requestRunner;
private ExpressionFormatter _expressionFormatter;

public RequestExecutor(string urlBase, DatabaseSchema schema, IAdapterTransaction transaction = null)
{
Expand All @@ -51,6 +52,7 @@ public RequestExecutor(string urlBase, DatabaseSchema schema, IAdapterTransactio
_requestRunner = transaction == null
? new CommandRequestRunner()
: (transaction as ODataAdapterTransaction).RequestRunner;
_expressionFormatter = new ExpressionFormatter(DatabaseSchema.Get(_urlBase).FindTable);
}

public IEnumerable<IDictionary<string, object>> FindEntries(string commandText, bool scalarResult, bool setTotalCount, out int totalCount)
Expand Down Expand Up @@ -85,21 +87,19 @@ public RequestExecutor(string urlBase, DatabaseSchema schema, IAdapterTransactio
return result;
}

public int UpdateEntry(string tableName, string keys, IDictionary<string, object> updatedData, bool merge, IAdapterTransaction transaction)
public int UpdateEntry(string tableName, IDictionary<string, object> entry, IDictionary<string, object> data, IAdapterTransaction transaction)
{
Dictionary<string, object> allData = new Dictionary<string, object>();
updatedData.Keys.ToList().ForEach(x => allData.Add(x, updatedData[x]));
bool merge = CheckMergeConditions(tableName, entry, data);
var commandText = FormatGetKeyCommand(tableName, entry);

var entryMembers = ParseEntryMembers(tableName, allData);

var entry = ODataClient.CreateDataElement(entryMembers.Properties);
var entryMembers = ParseEntryMembers(tableName, data);
var entryElement = ODataClient.CreateDataElement(entryMembers.Properties);
foreach (var association in entryMembers.AssociationsByValue)
{
CreateLink(entry, tableName, association);
CreateLink(entryElement, tableName, association);
}

var commandText = GetTableActualName(tableName) + "(" + keys + ")";
var command = new HttpCommand(merge ? RestVerbs.MERGE : RestVerbs.PUT, commandText, updatedData, entry.ToString());
var command = new HttpCommand(merge ? RestVerbs.MERGE : RestVerbs.PUT, commandText, data, entryElement.ToString());
_requestBuilder.AddCommandToRequest(command);
var result = _requestRunner.UpdateEntry(command);

Expand All @@ -113,9 +113,9 @@ public int UpdateEntry(string tableName, string keys, IDictionary<string, object
return result;
}

public int DeleteEntry(string tableName, string keys, IAdapterTransaction transaction)
public int DeleteEntry(string tableName, IDictionary<string, object> entry, IAdapterTransaction transaction)
{
var commandText = GetTableActualName(tableName) + "(" + keys + ")";
var commandText = FormatGetKeyCommand(tableName, entry);
var command = HttpCommand.Delete(commandText);
_requestBuilder.AddCommandToRequest(command);
return _requestRunner.DeleteEntry(command);
Expand Down Expand Up @@ -147,16 +147,15 @@ private void CreateLink(XElement entry, string tableName, KeyValuePair<string, o

var association = _schema.FindTable(tableName).FindAssociation(associatedData.Key);
var entryProperties = GetLinkedEntryProperties(associatedData.Value);
var keyFieldNames = _schema.FindTable(association.ReferenceTableName).PrimaryKey.AsEnumerable().ToArray();
var keyFieldValues = new object[keyFieldNames.Count()];

for (int index = 0; index < keyFieldNames.Count(); index++)
var associatedKeyNames = _schema.FindTable(association.ReferenceTableName).GetKeyNames();
var associatedKeyValues = new object[associatedKeyNames.Count()];
for (int index = 0; index < associatedKeyNames.Count(); index++)
{
bool ok = entryProperties.TryGetValue(keyFieldNames[index], out keyFieldValues[index]);
bool ok = entryProperties.TryGetValue(associatedKeyNames[index], out associatedKeyValues[index]);
if (!ok)
return;
}
ODataClient.AddDataLink(entry, association.ActualName, association.ReferenceTableName, keyFieldValues);
ODataClient.AddDataLink(entry, association.ActualName, association.ReferenceTableName, associatedKeyValues);
}

private IDictionary<string, object> GetLinkedEntryProperties(object entryData)
Expand Down Expand Up @@ -235,5 +234,34 @@ private string GetTableActualName(string tableName)
{
return _schema.FindTable(tableName).ActualName;
}

private string FormatGetKeyCommand(string tableName, IDictionary<string, object> entry)
{
var keyNames = _schema.FindTable(tableName).GetKeyNames();
var keyValues = new List<object>();
foreach (var keyName in keyNames)
{
object keyValue;
if (entry.TryGetValue(keyName, out keyValue))
{
keyValues.Add(keyValue);
}
}
var formattedKeyValues = _expressionFormatter.Format(keyValues);
return GetTableActualName(tableName) + "(" + formattedKeyValues + ")";
}

private bool CheckMergeConditions(string tableName, IDictionary<string, object> entry, IDictionary<string, object> data)
{
var keyNames = _schema.FindTable(tableName).GetKeyNames();
foreach (var key in entry.Keys)
{
if (!keyNames.Contains(key) && !data.Keys.Contains(key))
{
return true;
}
}
return false;
}
}
}
}

0 comments on commit 8ad5a1f

Please sign in to comment.