Drools - extract Map embedded inside a Map - drools

here is my data structure :
public class Premium{
private Map<String,Map<String,String>> valuesMap = new HashMap<String,Map<String,String>>();
public Map<String, Map<String, String>> getValuesMap() {
return valuesMap;
}
}
Sample values that will be present inside this 'valuesMap' :
Map<String,String> m1= new HashMap<String,String>();
m1.put("death","100");
m1.put("income","50");
valuesMap.put("Male",m1);
valuesMap.put("Female",m2);
....
So where I am struggling with is how do I extract the map 'm1' embedded within 'valuesMap' for "Male" ?
Once I can do that then I can think of looking into extracting values from within 'm1'
Here is what I have tried and nothing seems to work ...
rule "rule#7 testing me 001 "
when
// below line extracts 'valuesMap' from Premium object
$pr:Premium($masterMap:valuesMap)
// no error but does not go into 'then' and print SOP
//$map :Map(this["Male"]);
//$map :Map(this["Male"] != null);
// error : java.lang.ClassCastException: java.util.HashMap cannot be cast to java.lang.Boolean
//$map : Map(this["Male"] ) from $masterMap
// prints Values Map and not the embedded map for both the below attempts
//$map : Map(this["Male"] != "") from $masterMap
//$map : Map(this["Male"] != null ) from $masterMap
// tried java way but getting error : Unable to resolve ObjectType '$masterMap.get' : [Rule name='rule#7 testing me 001 ']
//$map : $masterMap.get("Male");
// no error but did not fire then condition and print sop
//$map : Map($masterMap.get("Male"));
// error : Unable to resolve ObjectType '$masterMap.getGet' : [Rule name='rule#7 testing me 001 ']
//$map : $masterMap.getGet("Male");
//error : Unable to resolve ObjectType '$masterMap.get' : [Rule name='rule#7 testing me 001 ']
//$map : $masterMap.get("Male") from $masterMap
then
System.out.println("rule#7 map " + $map);
end

$pr: Premium( $masterMap: valuesMap )
Map( $male: this["Male"] ) from $masterMap
You really should try and avoid using Maps in your rules. That nested map structure is frankly bad practice in general. In rules, Maps are extremely non-performant -- many years ago (10+) it was s.o.p. to pass Maps into rules, but then we figured out how bad it was. ;)

Related

ServiceStack Ormlite Deserialize Array for In Clause

I am storing some query criteria in the db via a ToJson() on the object that contains all the criteria. A simplified example would be:
{"FirstName" :[ {Operator: "=", Value: "John"}, { Operator: "in", Value:" ["Smith", "Jones"]"}], "SomeId": [Operator: "in", Value: "[1,2,3]" }]}
The lists are either string, int, decimal or date. These all map to the same class/table so it is easy via reflection to get FirstName or SomeId's type.
I'm trying to create a where clause based on this information:
if (critKey.Operator == "in")
{
wb.Values.Add(keySave + i, (object)ConvertList<Members>(key,
(string)critKey.Value));
wb.WhereClause = wb.WhereClause + " And {0} {1} (#{2})".Fmt(critKey.Column,
critKey.Operator, keySave + i);
}
else
{
wb.Values.Add(keySave + i, (object)critKey.Value);
wb.WhereClause = wb.WhereClause + " And {0} {1} #{2}".Fmt(critKey.Column, critKey.Operator, keySave + i);
}
It generates something like this (example from my tests, yes I know the storenumber part is stupid):
Email = #Email0 And StoreNumber = #StoreNumber0 And StoreNumber in (#StoreNumber1)
I'm running into an issue with the lists. Is there a nice way to do this with any of the ormlite tools instead of doing this all by hand? The where clause generates fine except when dealing with lists. I'm trying to make it generic but having a hard time on that part.
Second question maybe related but I can't seem to find how to use parameters with in. Coming from NPoco you can do (colum in #0, somearray)` but I cant' seem to find out how to do this without using Sql.In.
I ended up having to write my own parser as it seems ormlite doesn't support have the same support for query params for lists like NPoco. Basically I'd prefer to be able to do this:
Where("SomeId in #Ids") and pass in a parameter but ended up with this code:
listObject = ConvertListObject<Members>(key, (string)critKey.Value);
wb.WhereClause = wb.WhereClause + " And {0} {1} ({2})"
.Fmt(critKey.Column, critKey.Operator,listObject.EscapedList(ColumnType<Members>(key)));
public static string EscapedList(this List<object> val, Type t)
{
var escapedList = "";
if (t == typeof(int) || t == typeof(float) || t == typeof(decimal))
{
escapedList = String.Join(",", val.Select(x=>x.ToString()));
} else
{
escapedList = String.Join(",", val.Select(x=>"'" + x.ToString() + "'"));
}
return escapedList;
}
I'd like to see other answers especially if I'm missing something in ormlite.
When dealing with lists you can use the following example
var storeNumbers = new [] { "store1", "store2", "store3" };
var ev = Db.From<MyClass>
.Where(p => storeNumbers.Contains(p => p.StoreNumber));
var result = Db.Select(ev);

Error when trying to insert the result of a accumulate function(intValue) into a hashmap<String, Integer>()

I tried to insert a value into a Hashmap() but my test case fails when I tried to put the result of an accumulate function($totals in the drl file) as the value of the Hashmap. I've also tried Integer.valueOf($totals) instead of $totals without luck.
My drl file contains:
rule "calculate total per item"
no-loop
when
$o : Order( $lines : orderLines)
$ol : OrderLine(this memberOf $lines.values() , quantity > 0)
$totals : Number(intValue > 0) from accumulate (
OrderLine($qty : quantity, item.barcode == $ol.getItem().getBarcode()) from $lines.values(),
sum($qty)
)
then
System.out.println("total: " + $totals); //prints out total: 7.0
modify($o){
getPerItems().put($ol.getItem().getBarcode(), $totals); //this line throws an error
//getPerItems().put($ol.getItem().getBarcode(), 1 ); // If I replace $totals with a number, it works
}
end
My Order class
public class Order {
private HashMap<Integer, OrderLine> orderLines = new HashMap<Integer, OrderLine>();
private HashMap<String, Integer> perItems = new HashMap<String, Integer>();
...
public HashMap<String, Integer> getPerItems() {
return perItems;
}
}
Any advice to overcome this issue?
Try this binding:
Number($totals : intValue > 0)
It would help if you add the error message verbatim to your question.
"Throws an error" - does it mean "throws an exception" or "reports an error". When and where ...?

Django-Tastypie-MongoEngine, How To Serialize Data - Create Response Method When Using prepend_urls

I have the following Resource and am attempting to prepend a url to the api and get all the clubs for a manufacturer resource. Currently, I am just trying to get a response with all clubs (notice I just do a objects.all(), because I am just wanting data at this point, I'll filter it later). My issue is that when I hit the url, I do indeed get clubs, however, they aren't in json format, the result looks like this:
"[<Club: Club object>, <Club: Club object>]"
What do I need to add to the create_response so that it will return the json formatted object so that it can be used - basically, have it blow out the objects instead of leaving them as
"[<Club: Club object>]"
Here is what a club looks like:
{
"_id" : "5275b295fa57952e260243e5|Fairway|1",
"manufacturer" : "Adams",
"head_material" : null,
"image_url" : "https://blah.com",
"year" : "0",
"name" : "Tight Lies GT Xtreme Offset",
"url" : "http://blah.com"
}
Here is the resource:
class ManufacturerResource(resources.MongoEngineResource):
class Meta:
queryset = documents.Manufacturer.objects.all().order_by('id')
allowed_methods = ('get')
resource_name = 'manufacturers'
include_resource_uri = False
def prepend_urls(self):
return [
url(r"^(?P<resource_name>%s)/(?P<pk>[\w\d_.-]+)/drivers/$" % self._meta.resource_name, self.wrap_view('get_manufacturer_drivers'), name="api_get_manufacturer_drivers"),
]
def get_manufacturer_drivers(self, request, **kwargs):
drivers = documents.Club.objects.all().order_by('id')
return self.create_response(request, drivers)
I ended up figuring this out after digging and digging. I couldn't find anything built in that did what I created. What I did was created a HelperMethod class with some static methods. Here is was I came up with:
class HelperMethods:
#staticmethod
def obj_to_dict(object):
return_data = {}
for property, value in vars(object).iteritems():
return_data[property] = value
return return_data['_data']
#staticmethod
def obj_to_list(objects):
return_data = []
for object in objects:
return_data.append(HelperMethods.obj_to_dict(object))
return return_data
Usage:
return self.create_response(request, HelperMethods.obj_to_list(drivers))
Hope this helps someone.

can i use custom lambda method in entity framework?

i have some methods like:
public static string ToOtherFormat (this string inp)
{
// some code to change inp
return inp;
}
and in my select i want to have code like this:
var DetailMembers = db.TB_Members
.Where(x=> x.FName == obj.ToOtherFormat())
.Select( x=> new { name = (x.FName.ToOtherFormat() + " " + x.LName) , x.ActCode });
i try and just have error. is it possible?
thanks!
i receive this error in simple convert to integer
LINQ to Entities does not recognize the method 'Int32 ToInt32(System.String)' method, and this method cannot be translated into a store expression.
with this code
.Where(x => x.MemberID == Convert.ToInt32(Hmemid.Hash_two_Decrypt())
Looks like you are querying against the database. Your current query will get translated into SQL query and since SQL doesn't recognize your function that is why you get error.
You may get the data from the tables using a query without that function and then later do the formatting on the result set.
i found it on use .AsEnumerable() method like:
var DetailMembers = db.TB_Members.AsEnumerable()
.Where(x=> x.FName == obj.ToOtherFormat())
.Select( x=> new { name = (x.FName.ToOtherFormat() + " " + x.LName) , x.ActCode });

Declare new type Jboss Drools

i need declare a new type in my drl like this example.
package com.sample
import com.sample.DroolsTest.Message;
declare Variavel
valor : Integer
end
rule "Hello World"
when
m : Message( status == Message.HELLO, myMessage : message )
-----> v : Variavel() Problem here, the variable is not instantiated
then
System.out.println( myMessage );
m.setMessage( "Goodbye cruel world" );
m.setStatus( Message.GOODBYE );
update( m );
end
rule "GoodBye"
when
Message( status == Message.GOODBYE, myMessage : message )
then
System.out.println( myMessage );
end
My problem: I want use the variable without put this code
FactType personType = kbase.getFactType( "com.sample","Variavel" );
Object test = personType.newInstance();
ksession.insert(test);
Its possible use the declared field without put this code when i fire the rule, like a static field?
A type declaration in Drools is like declaring a class in Java. You have the type there, but no instances. What you can do is have a higher priority rule instantiate and insert it as a fact instead of having the application doing it. E.g.:
declare Variavel
valor : Integer
end
rule "create variable"
salience 100
when
then
insert( new Variavel() );
end
rule "Hello World"
when
m : Message( status == Message.HELLO, myMessage : message )
v : Variavel()
then
// do something
end