BreezeJS/Query - Predicate on expanded field issue - breeze

var p1 = breeze.Predicate.create("Status", "==", 3);
var p2 = breeze.Predicate.create("Client/Status", "==", 1);
var p = breeze.Predicate.and([p1, p2]);
In the above code, the final predicate p gets converted as:
(Status eq 3) and (Client/Status eq '1')
when it is viewed in Fiddler/Web inspector xhr view.
Why is the integer number 1 is considered as string ('1') when a predicate is created on an expanded entity's field ("Client/Status", see predicate p2). This causes the http request to fail as a bad request.
The same kind of predicate is constructed correctly on a first level field ("Status", see predicate p1).
Note: This request works fine when I go to Fiddler, remove the single quotes around the value 1 and execute.

I think the issue is that you need to use a dots '.' to separate the parts of the path instead of a '/'. i.e.
var p2 = breeze.Predicate.create("Client.Status", "==", 1);
The reason that you are seeing 'Client/Status' interpreted as a string is that breeze defaults values to strings when it is unable to determine the actual datatype of the field. It determines the datatype by navigating the path and determining the datatype of each segment via metadata.
Hope this helps.

Related

Mule 4 - Set Start Date & End Date as QueryParams

I'm having trouble defining both start and end dates as a query parameters. When the data gets pulled, it needs to return as a range of dates based on the query parameters. The GET URL would look like http://localhost:8081/test?FileType=Sales&StartDate=2022-10-01&EndDate=2022-10-26. This should return a date range of data from 10/1/2022-10/26/2022.
In my query, my where clause is set to:
where dp.Nid = 405 and fs.DDate=:DDate
**dp and fs are used in my joins and 405 is an ID that i'll need to unique identify a product.
My input Parameters:
{ DDate : attributes.queryParams.StartDate, DDate : attributes.queryParams.EndDate }
What do i need to set to make a range of dates? Do i need to set startdate to > and enddate to < ? Also, is it possible to define query parameters when using a stored procedure instead of select database method in anypoint studio?
Operations in Mule 4 (ie the boxes inside a flow) can have several inputs (payload, variables, attributes) and 1 output, but they are expected to be independent from each other. The Database query operation doesn't care if its inputs come the query params or from somewhere else. You need to map inputs explicitly to parameters in the query.
Once you have the arguments you need to use them in the SQL query. Usually that means adding a greater than and a lesser than comparison, to ensure that the value is in range. Or the same including also equals, if the business logic requires it.
Depending on the data types and the SQL dialect you may need to convert the inputs to a date format that is compatible with the database type of the column. The inputs here are strings, because that's what query params always are parsed to. The column type is something that you will need to understand and see how to transform, in DataWeave or in the SQL query.
As an example:
<db:select config-ref="dbConfig">
<db:sql>SELECT ... WHERE dp.Nid = 405 AND fs.DDate >= :StartDate AND fs.DDate <= :StartDate</db:sql>
<db:input-parameters>
#[{
StartDate : attributes.queryParams.StartDate,
EndDate : attributes.queryParams.EndDate
}]
</db:input-parameters>
</db:select>

Need help in understanding the Erlang code and what exactly it is doing

I am finding it difficult to decipher this code. I could understand that there is an instance of a data structure; is it a record or map?
The query is regarding the last two line of the code does it update the record with Response or does it check message_code?
Response =
#{header =>
#{message_code => 'CONN_ESTABLISH_REQUEST',
protocol_instance => ?MGMT_PROTOCOL_IDENTIFIER,
transaction_identifier => 1},
content => #{revision_list => [0]}
},
#{header := #{message_code := 'CONN_ESTABLISH_CONFIRM'},
content := Confirmation} = Response
It's a map, not a record. (If it were a record, the record name would be between the # and the {.)
The last two lines perform a pattern match on the variable Response. The code asserts that Response is a map containing at least two keys, header and content. The value for header must be a map containing at least one key, message_code, whose value is 'CONN_ESTABLISH_CONFIRM'. The value for content will be stored in the variable Confirmation.
If the value of Response doesn't conform to all those requirements, this code will signal a badmatch error.
Note that the behaviour is different depending on whether the right hand side of := contains:
a constant
an unbound variable
a bound variable (a variable that already has a value)
If it is an unbound variable, the value for that key is simply stored in that variable. If it is a bound variable, the value for that key must match the value of that variable, otherwise you get a badmatch error just like for a non-matching constant.
As you see, there are two different delimiters used, => and :=. When constructing a new map (such as the first expression in your example), you can only use =>, and when pattern matching, you can only use :=. The idea is that they do different things: => stores a key-value pair in the map, while := extracts an existing key-value pair.
There is another case: updating an existing map. In that case you can use both. => can be used to add a new key to the map, while := can only be used to update an existing key, otherwise it signals a badarg error. For example, if you wanted to add a "footer" to Response, you have to use =>:
NewResponse = Response#{footer => [some,data]},
%% this signals a badarg error:
NewResponse = Response#{footer := [some,data]},
while if you want to change the content, you can use either:
NewResponse = Response#{content := 42},
NewResponse = Response#{content => 42},

How to tell mapserver to ignore a filter?

I have a filter that I don't want to use at the launch of the application, only on a certain action. I know there is already a question about this but it doesn't help me, I actually don't understand both of the answers.
I was in a logic of "my column = value or 1 = 1" to get all my datasets instead of just the filter if it's not called.
Here's what I wrote :
FILTER (([ct]='%ct%') or '%ct%' = '%ct%')
VALIDATION
'ct' '^[a-zA-Z\-]+$'
END
I call my layer with a param on Openlayers 3 with
url: 'http://localhost:5000/cgi-bin/mapserv.exe?map=/ms4w/apps/tutorial/htdocs/essai.map&SERVICE=WMS&VERSION=1.1.1%20&REQUEST=GetCapabilities',
serverType: 'mapserver',
params: {'LAYERS': 'aisdata', 'ct':'myvalue', 'TILED': true}
});
But all my dataset is returned. (If I remove '%ct%' = '%ct%' in my mapfile, the filter is well applied)
Can anyone help me to ignore my condition please?
Add a default value in the VALIDATION block, so that your value defaults to a empty string, and than add a OR condition in the FILER block which check if the value is a empty string:
VALIDATION
'ct' '^[a-zA-Z\-]+$'
'default_ct' '' # <-- ct will be a empty string if not provided via URL
END
FILTER (([ct]='%ct%') or ('%ct%' = '') )
If the database column ct does have a numeric type, the previous filter will produce a internal server error, because you cannot compare a empty string with a number. In this case use a numeric value as default, something like 0 or -1.

Returning multi value in dynamic query using neo4j client

Following the question I asked: Build a dynamic query using neo4j client
I got an answer about how can I return value dynamically using string only.
When I'm trying to use the syntax to return multi values from the query it failed,
I tried the following query:
var resQuery2 = WebApiConfig.GraphClient.Cypher
.Match("(movie:Movie {title:{title}})")
.OptionalMatch("(movie)<-[r]-(person:Person)")
.WithParam("title", title)
.Return(() => Return.As<string>("movie, collect([person.name, head(split(lower(type(r)), '_')), r.roles])"));
I'm getting the following error:
The deserializer is running in single column mode, but the response
included multiple columns which indicates a projection instead. If
using the fluent Cypher interface, use the overload of Return that
takes a lambda or object instead of single string. (The overload with
a single string is for an identity, not raw query text: we can't map
the columns back out if you just supply raw query text.)
Is it possible to return multiple nodes using only strings?
We can't get an output like in the question you asked previously - this is due to the fact that you are asking for a Node (the movie) and a Collection of strings (the collect) and they have no common properties, or even styles of property.
Firstly, let's look at the painful way to do this:
var q = gc.Cypher
.Match("(movie:Movie)")
.OptionalMatch("(movie)<-[r]-(person:Person)")
.Return(() => Return.As<string>("{movie:movie, roles:collect([person.name, head(split(lower(type(r)), '_')), r.roles])}"));
var results = q.Results;
Here we take the query items (movie, r, person) and create a type with them the {} around the results, and cast that to a string.
This will give you a horrible string with the Node data around the movie and then a collection of the roles:
foreach (var m in results)
{
//This is going to be painful to navigate/use
dynamic d = JsonConvert.DeserializeObject<dynamic>(m);
Console.WriteLine(d.movie);
Console.WriteLine(d.roles);
}
You'd be a lot better off doing something like:
var q = gc.Cypher
.Match("(movie:Movie)")
.OptionalMatch("(movie)<-[r]-(person:Person)")
.Return(() => new
{
Movie = Return.As<Node<string>>("movie"),
Roles = Return.As<IEnumerable<string>>("collect([person.name, head(split(lower(type(r)), '_')), r.roles])")
});
var res = q.Results;
You could either JsonConvert.DeserializeObject<dynamic>() the Movie node, at your leisure, or write a strongly typed class.
In terms of a 'dynamic' object, I don't know how you were wanting to interact with the collect part of the return statement, if this doesn't help, you might need to update the question to show a usage expectation.

ActiveRecord Integer Column won't accept some Integer assignments

I'm seeing some genuinely bizarre behavior w/ ActiveRecord as it relates to assignment. I have an ActiveRecord model named Venue that includes the measurements of the Venue, all integers less than 1K. We add Venues via an XML feed. On the model itself, I have a Venue.from_xml_feed method takes the XML, parses, and creates Venues.
The problem comes from the measurements. Using Nokogiri, I'm parsing out the measurements like so:
elems = xml.xpath("//*[#id]")
elems.each do |node|
distance = node.css("distances")
rs = distance.attr("rs")
// get the rest of the sides
# using new instead of create to print right_side, behavior is the same
venue = Venue.new right_side: rs # etc
venue.save
puts venue.right_side
end
The problem is that venue.right_side ALWAYS evaluates to nil, even though distance.attr("rs") contains a legal value, say 400. So this code:
rs = distance.attr("rs")
puts rs
Venue.new right_side: rs
Will print 400, then save rs as nil. If I try any type of Type Conversions, like so:
content = distance.attr("rs").content
str = content.to_s
int = Integer(str)
puts "Is int and Integer? #{int.is_a? Integer}"
Venue.new right_side: int
It will print Is int an Integer? true, then again save again save Venue.right_side as nil.
However, if I just explicitly create a random integer like so:
int = 400
Venue.new right_side: int
It will save Venue.right_side as 400. Can anyone tell me what's going on with this?
Well, you failed to include the prerequisite sample XML to confirm this, so you get a fairly generic answer.
In your code you're using:
distance = node.css("distances")
rs = distance.attr("rs")
css doesn't return what you think it does. It returns a NodeSet, which is similar to an Array. When you try to use attr on a NodeSet, you're going to set the value, not retrieve it. From the documentation:
#attr(key, value = nil, &blk) ⇒ Object (also: #set, #attribute)
Set the attribute key to value or the return value of blk on all Node objects in the NodeSet.
Because you're not using a value, the resulting action is to remove the attribute from the tag, which will then return nil and Ruby will assign nil to rs.
If you want to get the attribute of a node, you need to point to the node itself, so use at, or at_css, either of which returns a Node. Once you have the node, you can use attribute to retrieve the value, or use the [] shortcut similar to this untested code:
rs = node.at('distances')['rs']
Again though, because you didn't supply XML it's not possible to tell what else you might be trying to do, or whether this code is entirely accurate.

Resources