graphql-spqr: How to add a GraphQL property to an entity - graphql

I have a basic Java entity class.
public class Result {
String resultTitle;
String resultDecription;
}
This class is returned in a GraphQL query
#GraphQLQuery(name = "getResult")
public Result getResult() {
Result result = //get result, e.g. from DB
return result;
}
This works fine so far. Now I want to return one additional attribute in the GraphQL query. But that additonal attribute is very costly to calculate. So I only want to return it, when the GraphQL client actually requests it in his query like so:
query { getResult() { resultTitle resultDecription } } <== do not execute the costly calculation
query { getResult() { resultTitle resultDecription costlyAdditionalProp } } <== DO execute the costly calculation
Can this be done with graphql-spqr?

Oh, that was actually quite simple. Just needed to dig up the right example from the graphql-spqr-examples.
#GraphQLQuery(name = "costlyAdditionalProp ")
public Long getCostlyAdditionalProp (#GraphQLContext Result result) {
return calculationService.doCalculation(result);
}

Related

Is there a significant difference between these two linq methods?

We have some repo methods, and I see a lot of our team using our GetAll() method over another (Get()):
Example use case:
var user = _uow.UserRepository.GetAll().Include(x => x.UserMap).Include(x=>x.UserFile).Include(x=>x.UserDomains).FirstOrDefault(x => emails.Contains(x.Email));
I'm wondering if instead they be using this one?
var user = _uow.UserRepository.Get(x => emails.Contains(x.Email), "UserMap,UserFile,UserDomains");
Here are those two methods:
public virtual TEntity Get(Expression<Func<TEntity, bool>> filter = null, string includeTables = "")
{
IQueryable<TEntity> query = _entities;
if (filter != null)
query = query.Where(filter);
foreach (var includeTable in includeTables.Split(new char[] { ',' },
StringSplitOptions.RemoveEmptyEntries))
{
query = query.Include(includeTable);
}
return query.FirstOrDefault();
}
public IQueryable<TEntity> GetAll()
{
return _entities.AsQueryable();
}
Is the Get() method more efficient than the GetAll() method? In my mind, the GetAll() method is calling everything in the table (we're using a Repository pattern with one repository per table), then narrowing down afterward, whereas the Get() is being more specific.
Can anyone tell me if my intuition is right or wrong about this? I'm wondering how efficient that GetAll() is given the use-case.

I want to post ArrayList, but return null value

POSTMAN :
{
"childDTO":[{
"age":"80",
"gender":"kavi",
"occupation":"main",
"type":"mainlife"
},
{ "age":"80",
"gender":"kavi",
"occupation":"main",
"type":"mainlife"
}
]
}
Controller.....
#PostMapping("/child")
public List<CustomerDTO> childDTO(#RequestBody CustomerDTO cus){
return calculationService.childDTO(cus.getAge(),cus.getGender(),cus.getOccupation(),cus.getType());
}
Service......
public List<CustomerDTO> childDTO(String age, String gender, String occupation, String type);
Service Impl......
#Override
public List<CustomerDTO> childDTO(String age, String gender, String occupation, String type) {
List<CustomerDTO> typeChild = new ArrayList<>();
if (type==children) {
for (CustomerDTO customer1 : typeChild) {
customer1.setAge(age);
customer1.setGender(gender);
customer1.setOccupation(occupation);
customer1.setType(type);
customer1.setBenifits(benifitDTO(beni.getRiders(), beni.getSumAssuarance()));
System.out.println("list:-"+customer1);
typeChild.add(customer1);
}
}
System.out.println("list:-"+typeChild);
return typeChild;
}
You did not post what variable children is, probably some class field, but you cannot compare Java Strings with ==. Java Strings must be compared with .equals:
...
if (type.equals(children)) {
...
Use a debugger next time, to see what's happening in your code.
Your request and controller RequestBody structure do not match.
You need to use List.
#PostMapping("/child")
public List<CustomerDTO> childDTO(#RequestBody List<CustomerDTO> cusList){ // here list needs to be used
if(cusList != null && !cusList.isEmpty()) {
CustomerDTO cus = cusList.get(0); // it will get first element from the list, if you want to process all the elements then you need to iterate the list
return calculationService.childDTO(cus.getAge(),cus.getGender(),cus.getOccupation(),cus.getType());
}
}
Now other logic will be as it or you may change it as per your requirement.

How do you manually construct a lambda expression?

I'm designing an application using ASP.NET Web API and Entity Framework 5 and LINQ to Entities. The Web API doesn't serve up the entities directly, it converts them to a set of data transfer objects that are similar but not identical to my entities. The API will be used by a Silverlight application initially but I will have to support non-.NET clients (e.g. iOS apps) down the road. I'd also like to give the client the ability to run a robust set of queries against the API.
These requirements have lead me to consider the query object pattern. Essentially, I want to create a homegrown query object client-side, post it to the Web API, and convert the query object to a lambda expression that I can use in LINQ to Entities. This last part is what's tripping me up.
Starting with a simple comparison query, I want to be able to convert an object that looks like the following into a lambda expression at runtime.
public enum QueryOperator
{
None = 0,
GreaterThan,
GreaterThanOrEqualTo,
EqualTo,
NotEqualTo,
LessThanOrEqualTo,
LessThan
}
public class SimpleQuery<T>
{
public SimpleQuery()
{
this.Field = null;
this.Operator = QueryOperator.None;
this.Value = null;
}
public string Field { get; set; }
public QueryOperator Operator { get; set; }
public object Value { get; set; }
public IEnumerable<T> Execute(IQueryable<T> queryTarget)
{
// ????
}
}
How can I do this?
I've had to do things like this in the past. Here's what I came up with:
public IEnumerable<T> Execute(IQueryable<T> queryTarget)
{
return queryTarget.Where(this.GetWhereExpression<T>());
}
private Expression<Func<T, bool>> GetWhereExpression<T>()
{
var param = Expression.Parameter(typeof(T), "x");
var prop = Expression.Property(param, this.Field);
var value = Expression.Constant(this.Value, prop.Type);
Expression compare = null;
switch(this.Operator)
{
case QueryOperator.EqualTo:
compare = Expression.Equal(prop, value);
break;
...
}
return Expression.Lambda(compare, param);
}

Hive UDF Execution

I have written a Hive UDF that does decryption using an in-house API as follows:
public Text evaluate(String customer) {
String result = new String();
if (customer == null) { return null; }
try {
result = com.voltage.data.access.Data.decrypt(customer.toString(), "name");
} catch (Exception e) {
return new Text(e.getMessage());
}
return new Text(result);
}
and Data.decrypt does:
public static String decrypt(String data, String type) throws Exception {
configure();
String FORMAT = new String();
if (type.equals("ccn")) {
FORMAT = "CC";
} else if (type.equals("ssn")) {
FORMAT = "SSN";
} else if (type.equals("name")) {
FORMAT = "AlphaNumeric";
}
return library.FPEAccess(identity, LibraryContext.getFPE_FORMAT_CUSTOM(),String.format("formatName=%s", FORMAT),authMethod, authInfo, data);
}
where configure() creates a pretty expensive context object.
My question is: Does Hive execute this UDF once for every row returned by the query? i.e. If I'm selecting 10,000 rows, does the evaluate method get run 10,000 times?
My gut instinct tells me yes. And if so, then here's a second question:
Is there any way I can do one of the following:
a) run configure() once when the query first starts, then share the context object
b) instead of the UDF returning a decrypted string, it aggregates the encrypted string into some Set, then I do a bulk decrypt on the set?
Thanks in advance
Is configure() something that needs to be called once per JVM, or once per instance of the UDF class?
If once per JVM, just put it in a static block in the class, like so:
static {
configure();
}
If once per instance, put it in the constructor:
public [class name]() {
super();
configure();
}

Moq testing LINQ Where queries

I'm using EF 4.1 to build a domain model. I have a Task class with a Validate(string userCode) method and in it I want to ensure the user code maps to a valid user in the database, so:
public static bool Validate(string userCode)
{
IDbSet<User> users = db.Set<User>();
var results = from u in users
where u.UserCode.Equals(userCode)
select u;
return results.FirstOrDefault() != null;
}
I can use Moq to mock IDbSet no problem. But ran into trouble with the Where call:
User user = new User { UserCode = "abc" };
IList<User> list = new List<User> { user };
var users = new Mock<IDbSet<User>>();
users.Setup(x => x.Where(It.IsAny<Expression<Func<User, bool>>>())).Returns(list.AsQueryable);
Initialization method JLTi.iRIS3.Tests.TaskTest.SetUp threw exception.
System.NotSupportedException: System.NotSupportedException: Expression
references a method that does not belong to the mocked object:
x => x.Where<User>(It.IsAny<Expression`1>()).
Other than creating a level of indirection (eg, using a ServiceLocator to get an object that runs the LINQ and then mock that method) I can't think of how else to test this, but I want to make sure there is no way before I introduce another layer. And I can see this kind of LINQ queries will be needed quite often so the service objects can quickly spiral out of control.
Could some kind soul help? Thanks!
There is an article on MSDN highlighting how to mock using moq:
The gist of it is to represent linq to entities operations with linq to objects.
var mockSet = new Mock<DbSet<Blog>>();
mockSet.As<IQueryable<Blog>>().Setup(m => m.Provider).Returns(data.Provider);
mockSet.As<IQueryable<Blog>>().Setup(m => m.Expression).Returns(data.Expression);
mockSet.As<IQueryable<Blog>>().Setup(m => m.ElementType).Returns(data.ElementType);
mockSet.As<IQueryable<Blog>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator());
As Ladislav points out there are disadvantages to this as Linq To Objects is simply different to Linq to Entities so it may result in false positives. But it now being an MSDN article it does point that it is at least possible and perhaps recommended in some cases?
One thing that may of changed since the original answers to this post is that the Entity Framework team have opened up areas of Entity Framework in EF 6.0 to make it easier to mock it's inners.
Although I have not tried this, because IDBSet implements IEnumerable you might have to mock the enumerator method so the linq statements will pick up your list of users. You don't actually want to mock linq but by the looks of your code you want to test whether you are finding the right user based on the UserCode which I think is a valid unit test.
var user = new User { UserCode = "abc" };
var list = new List<User> { user };
var users = new Mock<IDbSet<User>>();
users.Setup(x => x.GetEnumerator()).Returns(list.GetEnumerator());
You might get a conflict with the non-generic version of the GetEnumerator but it this might help you on the right track.
Then you have to then place the mocked object on the data context which depends on other code that we don't see.
As I know Moq is able to set up only virtual methods of mocked object itself but you are trying to set up extensions (static) method - no way! These methods are absolutely outside of your mock scope.
Moreover that code is hard to test and requires too much initialization to be able to test it. Use this instead:
internal virtual IQueryable<User> GetUserSet()
{
return db.Set<User>();
}
public bool Validate(string userCode)
{
IQueryable<User> users = GetUserSet();
var results = from u in users
where u.UserCode.Equals(userCode)
select u;
return results.FirstOrDefault() != null;
}
You will just need to set up GetUserSet to return your list. Such testing has some major issues:
You are not testing the real implementation - in case of EF mocking sets is stupid approach because once you do it you change linq-to-entities to linq-to-objects. Those two are totally different and linq-to-entities is only small subset of linq-to-objects = your unit tests can pass with linq-to-objects but your code will fail at runtime.
Once you use this approach you cannot use Include because include is dependent on DbQuery / DbSet. Again you need integration test to use it.
This doesn't test that your lazy loading works
The better approach is removing your linq queries from Validate method - just call them as another virtual method of the object. Unit test your Validate method with mocked query methods and use integration tests to test queries themselves.
I found it easier just to write the stub:
internal class FakeDbSet<T> : IDbSet<T>where T : class
{
readonly HashSet<T> _data;
readonly IQueryable _query;
public FakeDbSet()
{
_data = new HashSet<T>();
_query = _data.AsQueryable();
}
public virtual T Find(params object[] keyValues)
{
throw new NotImplementedException("Derive from FakeDbSet<T> and override Find");
}
public T Add(T item)
{
_data.Add(item);
return item;
}
public T Remove(T item)
{
_data.Remove(item);
return item;
}
public T Attach(T item)
{
_data.Add(item);
return item;
}
public void Detach(T item)
{
_data.Remove(item);
}
Type IQueryable.ElementType
{
get { return _query.ElementType; }
}
Expression IQueryable.Expression
{
get { return _query.Expression; }
}
IQueryProvider IQueryable.Provider
{
get { return _query.Provider; }
}
IEnumerator IEnumerable.GetEnumerator()
{
return _data.GetEnumerator();
}
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
return _data.GetEnumerator();
}
public TDerivedEntity Create<TDerivedEntity>() where TDerivedEntity : class, T
{
return Activator.CreateInstance<TDerivedEntity>();
}
public T Create()
{
return Activator.CreateInstance<T>();
}
public ObservableCollection<T> Local
{
get
{
return new ObservableCollection<T>(_data);
}
}

Resources