Skip to content

Commit

Permalink
S-58164 WIP for FluentQuery formal support! #15
Browse files Browse the repository at this point in the history
  • Loading branch information
JogoShugh committed Apr 30, 2016
1 parent 4636e0d commit d189408
Show file tree
Hide file tree
Showing 19 changed files with 331 additions and 929 deletions.
6 changes: 6 additions & 0 deletions APIClient/Connector/V1Connector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,11 @@ ICanGetConnector ICanSetEndpointOrGetConnector.UseEndpoint(string endpoint)

return this;
}

public FluentQuery Query(string assetTypeName)
{
return new Services(this.Build()).Query(assetTypeName);
}
}

#endregion
Expand Down Expand Up @@ -587,6 +592,7 @@ public interface ICanSetProxyOrEndpointOrGetConnector : ICanSetEndpoint, ICanGet
/// <param name="proxyProvider">The ProxyProvider containing the proxy URI, username, and password.</param>
/// <returns>ICanSetEndpointOrGetConnector</returns>
ICanSetEndpointOrGetConnector WithProxy(ProxyProvider proxyProvider);
FluentQuery Query(string assetTypeName);
}

public interface ICanSetEndpointOrGetConnector : ICanGetConnector
Expand Down
64 changes: 63 additions & 1 deletion APIClient/Model/Asset/Asset.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;

namespace VersionOne.SDK.APIClient
{
public class Asset
public class Asset : DynamicObject
{
private Oid oid = Oid.Null;
private readonly IDictionary<string, Attribute> attributes = new Dictionary<string, Attribute>();
private readonly IAssetType assetType;
private readonly AssetList children = new AssetList();
protected string AssetBasePrefix { get; set; }
private IMetaModel metaModel;
private IServices services;

public IAssetType AssetType
{
Expand Down Expand Up @@ -56,6 +60,20 @@ public Asset(IAssetType assetType)
this.assetType = assetType;
}

public Asset(string basePrefix, IMetaModel metaModel, IServices services)
{
Configure(basePrefix, metaModel, services);
}

public void Configure(string basePrefix, IMetaModel metaModel, IServices services)
{
this.AssetBasePrefix = basePrefix;
this.metaModel = metaModel;
this.services = services;
}

public object this[string name] => GetValueByName(name);

public void SetAttributeValue(IAttributeDefinition attribdef, object value)
{
EnsureAttribute(attribdef).SetValue(value);
Expand Down Expand Up @@ -153,5 +171,49 @@ public Attribute EnsureAttribute(IAttributeDefinition attribdef)

return attrib;
}

#region DynamicObject members

public override bool TryGetMember(GetMemberBinder binder,
out object result)
{
var attribute = GetAttributeByName(binder.Name);
result = GetAttribute(attribute).Value;
return result != null;
}

public override bool TrySetMember(SetMemberBinder binder, object value)
{
var attribute = GetAttributeByName(binder.Name);
if (attribute != null)
{
SetAttributeValue(attribute, value);
return true;
}
return false;
}

#endregion

public IAttributeDefinition GetAttributeByName(object fieldName)
{
return metaModel.GetAttributeDefinition(AssetBasePrefix + "." + fieldName);
}

public object GetValueByName(string fieldName)
{
var attribute = GetAttributeByName(fieldName);
return GetAttribute(attribute).Value;
}

public void SaveChanges()
{
services.Save(this);
}

public void SaveChanges(string comment)
{
services.Save(this, comment);
}
}
}
170 changes: 170 additions & 0 deletions APIClient/Query/FluentQuery.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
using System;
using System.Collections.Generic;
using System.Linq;

namespace VersionOne.SDK.APIClient
{
public class FluentQuery
{
private IMetaModel metaModel;
private IServices services;
public Query RawQuery { get; set; }
public string AssetTypeName { get; set; }
public List<Tuple<string, object, FilterTerm.Operator>> WhereCriteria { get; set; }
public List<object> SelectFields { get; set; }
public Action<IEnumerable<Asset>> OnSuccess { get; set; }
public Action OnEmptyResults { get; set; }
public Action<Exception> OnError { get; set; }

public FluentQuery(
string assetTypeName, IMetaModel metaModel, IServices services)
{
this.metaModel = metaModel;
this.services = services;
AssetTypeName = assetTypeName;

WhereCriteria = new List<Tuple<string, object, FilterTerm.Operator>>();
SelectFields = new List<object>();
}

public FluentQuery Where(params Tuple<string, object, FilterTerm.Operator>[] criteria)
{
WhereCriteria.AddRange(criteria);

return this;
}

public FluentQuery Select(params object[] fields)
{
SelectFields.AddRange(fields);

return this;
}

public FluentQuery Success(Action<IEnumerable<Asset>> callback)
{
OnSuccess = callback;

return this;
}

public FluentQuery WhenEmpty(Action callback)
{
OnEmptyResults = callback;

return this;
}

public FluentQuery Error(Action<Exception> callback)
{
OnError = callback;

return this;
}

public FluentQuery Execute(Action<IEnumerable<Asset>> successCallback = null)
{
if (OnSuccess == null && successCallback == null)
{
throw new NullReferenceException("Must specify the OnSuccess callback before calling Execute or pass it directly to Execute as a parameter");
}

try
{
QueryResult result = RetrieveQueryResult();

if (result.Assets.Count == 0)
{
OnSuccess?.Invoke(result.Assets);
}

result.Assets.ForEach(a => a.Configure(AssetTypeName, metaModel, services));

if (result.Assets.Count == 0)
{
OnEmptyResults?.Invoke();
}

if (successCallback != null)
{
successCallback(result.Assets);
}
else
{
OnSuccess(result.Assets);
}
}
catch (Exception exception)
{
if (OnError != null)
{
OnError(exception);
}
else
{
throw;
}
}

return this;
}

private QueryResult RetrieveQueryResult()
{
RawQuery = new Query(metaModel.GetAssetType(AssetTypeName));

var attributes = new List<IAttributeDefinition>();

if (SelectFields.Count > 0)
{
attributes.AddRange(
SelectFields.Select(
m => metaModel.GetAttributeDefinition(AssetTypeName
+ "." + m.ToString())));
}
RawQuery.Selection.AddRange(attributes);

if (WhereCriteria.Count > 0)
{
var andTerms = new List<FilterTerm>();

foreach (var tuple in WhereCriteria)
{
var attribute = metaModel.GetAttributeDefinition(AssetTypeName
+ "." + tuple.Item1);
var item = tuple.Item2;
var term = new FilterTerm(attribute);
term.Operate(tuple.Item3, item);
andTerms.Add(term);
}

var andTerm = new AndFilterTerm(andTerms.ToArray());
RawQuery.Filter = andTerm;
}

var result = services.Retrieve(RawQuery);
return result;
}

public QueryResult Retrieve()
{
QueryResult result = null;
try
{
result = RetrieveQueryResult();
}
catch (Exception exception)
{
if (OnError != null)
{
OnError(exception);
}
else
{
throw;
}
}
return result;
}
}
}
1 change: 1 addition & 0 deletions APIClient/Services/IServices.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public interface IServices
string Localization(string key);
string Localization(IAttributeDefinition attribute);
Dictionary<string, string> Localization(params IAttributeDefinition[] attributes);
FluentQuery Query(string assetTypeName);

/// <summary>
/// Executes a query using the Query API (query.v1 endpoint).
Expand Down
5 changes: 5 additions & 0 deletions APIClient/Services/Services.cs
Original file line number Diff line number Diff line change
Expand Up @@ -720,5 +720,10 @@ private static void ParseAttributeNode(Asset asset, IAttributeDefinition attribd
}
}
}

public FluentQuery Query(string assetTypeName)
{
return new FluentQuery(assetTypeName, this.Meta, this);
}
}
}
1 change: 1 addition & 0 deletions APIClient/VersionOne.SDK.APIClient.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@
</Compile>
<Compile Include="Connector\V1Connector.cs" />
<Compile Include="Query\Builders\HierarchicalPartBuilder.cs" />
<Compile Include="Query\FluentQuery.cs" />
<Compile Include="Services\Services.cs" />
<Compile Include="Query\Builders\QueryURLBuilder.cs" />
<Compile Include="Obsolete\V1CredsAPIConnector.cs" />
Expand Down
69 changes: 0 additions & 69 deletions Example/GettingStarted/src/ApiVNext/AssetClassBase.cs

This file was deleted.

Loading

0 comments on commit d189408

Please sign in to comment.