Correct syntax for IS NULL values with Loopback and MySQL - mysql

I use Loopback (v3) to manage endpoints with a MySQL DB. From my app, I use Axios to get end point data.
In the DB, I have this kind of record:
id name value //other columns
1 Sally 0.00
2 Sally 135.00
3 Sally null
I can query each value in SQL:
select * from Tab where name = 'Sally' and value = 0;
select * from Tab where name = 'Sally' and value is null;
select * from Tab where name = 'Sally' and value > 0;
Problem: I can't replicate some of these queries with Axios from the app (nor with my curl tests). For example, I'd like to get only the null values and can't find the correct syntax for "is null" to put in a Loopback filter.
Here are the curls I tried:
curl -g http://my_ip/api/tabs <-- works as expected
curl -g http://my_ip/api/tabs\?filter\[where\]\[value\]\=null <-- returns only the 0 values and none of the null ones!
So, to spot only the null ones, I tried this solution:
curl -g http://my_ip/api/tabs\?filter\[where\]\[value\]\[eq\]\=null | jq .
It returns an error (and anyway, I can't find a "eq" operator in the list provided by the loopback docs.
How could I get the distinct 0 and null values with loopback, replicating what I got directly in MySQL? Is there a way to make a "is null" filter with Loopback?

Disclaimer: I am a co-author and maintainer of LoopBack.
Query string parameters have always a string value, it's not possible to tell whether the value null was meant as a string "null" or as JavaScript keyword null.
Fortunately LoopBack supports also JSON encoding for complex query string arguments. With JSON, it's easy to distinguish between numbers, strings and null values.
Here is the query to list all model instances with NULL value:
curl -g 'http://my_ip/api/tabs?filter={"where":{"value":null}}'
If you are building the request URL in JavaScript, just convert your filter argument from an object into a string via JSON.stringify and let your HTTP client library to URL-encode the value.
Here is a typical request you will get as a result:
http://my_ip/api/tabs?filter=%7B%22where%22%3A%7B%22value%22%3A%20null%7D%7D

Related

azure cli query return invalid type for value received null

Trying to query az repos policy list with query of:
[?type.displayName=='Build' && contains(settings.displayName, 'Test')] returning message:
Invalid jmespath query supplied for `--query`: In function contains(), invalid type for value: None, expected one of: ['array', 'string'], received: "null"
Data is present while i query the fields, but when trying to query the value of them it is complaining.
tried with --query "[?contains(settings.displayName, 'Test')]" resulting in the same error.
I came across a link to bug query will traceback while attempting to filter a nullable field which contained instead a helpful explanation:
The reason for to_string() is that some service principals have their homepage set to null which is not an array or string. So the jmespath library fails.
This can be remedied by calling to_string on each object's homepage field so that homepage is always a string for the purposes of contains()
so i updated my query: az repos policy list --query "[?type.displayName=='Build' && contains(to_string(settings.displayName), 'Test') ]"
which returned my exspected output.
Thanks.
One of the workaround you can follow to resolve the above issue;
You can specify the space between )& ] in the last section as suggested in this SO THREAD by #rcarrington
For example:-
--query "[?contains(settings.displayName, 'Test') ]"
If the above does not work then please try to give a space between ? & contains .
For more information please refer this MICROSOFT DOCUMENTATION| How to query Azure CLI command output using a JMESPath query .

AES_DECRYPT Getting the value from a blob in typescript

Coding an Angular 5/typescript client calling a node.js webserver talking to a MySQL DB. Had a successfully working call for names:
SELECT *
FROM stories JOIN users
ON stories.author_id=users.id
WHERE stories.story_id = 1;
If I need to encrypt the last names of authors at a field level in the DB, I could use AES_ENCRYPT and AES_DECRYPT. This changes the call to this. I used dlname here to distinguish the decrypted value from the lname field.
SELECT *, AES_DECRYPT(lname, UNHEX(SHA2('some phrase',512))) AS dlname
FROM stories JOIN users
ON stories.author_id=users.id
WHERE stories.story_id = 1;
This works in dev environment using phpMyAdmin, the dlname is fine on the return and shows as text. But when pushed to a prod env with MySQL and call it, the typescript (Angular 5 client) shows dlname as a blob [object Object]. I checked it with MySQL Workbench and it also shows it as a blob, which I can right-click on and then "Open value in viewer" and I see the last name just fine.
My question is, how do I write the typescript code to get the actual lname value out of the blob? The pertinent lines of code are...
this.http.get<StoryRes>(sRootURI + '/getStory/' + sDocID)
.subscribe(data => {
this.sAuthor = data[0].fname + ' ' + data[0].dlname;
In this case, the dlname shows in the console as [object Object].
I figured it out from some help found in BLOB data returned in MySQL using AES_DECRYPT with ORDER clause. Add a CAST(... AS CHAR) around your AES_DECRYPT function...
SELECT *, CAST(AES_DECRYPT(lname, UNHEX(SHA2('some phrase',512))) AS CHAR) as dlname...
On the client side, just make sure to call the new field name dlname instead of the actual name lname. Nothing additional is needed on the client side, will come through as text, as expected.

Spring data Couchbase #n1ql.fields query

I'm trying to make a N1QL based query on Spring Data Couchbase. The documentation says
#n1ql.fields will be replaced by the list of fields (eg. for a SELECT clause) necessary to reconstruct the entity.
My repository implementation is this one:
#Query("#{#n1ql.fields} WHERE #{#n1ql.filter}")
List<User> findAllByFields(String fields);
And I'm calling this query as follows:
this.userRepository.findAllByFields("SELECT firstName FROM default");
I'm getting this error:
Caused by: org.springframework.data.couchbase.core.CouchbaseQueryExecutionException: Unable to execute query due to the following n1ql errors:
{"msg":"syntax error - at AS","code":3000}
After a little bit of researching, I also tryed:
#Query("SELECT #{#n1ql.fields} FROM #{#n1ql.bucket} WHERE #{#n1ql.filter}")
With this query, I don't get an error, I get all the documents stored but only the ID the other fields are set to null, when my query tries to get the firstName field.
this.userRepository.findAllByFields("firstName");
Anyone knows how to do such a query?
Thank you in advance.
You're misunderstanding the concept, I encourage you to give the documentation more time and see more examples. I'm not sure what exactly you're trying to achieve but I'll throw some examples.
Find all users (with all of their stored data)
#Query("#{#n1ql.selectEntity} WHERE #{#n1ql.filter}")
List<User> findAllUsers();
This will basically generate SELECT meta().id,_cas,* FROM bucket WHERE type='com.example.User'
Notice findAllUsers() does not take any parameters because there are no param placeholders defined in the #Query above.
Find all users where firstName like
#Query("#{#n1ql.selectEntity} WHERE #{#n1ql.filter} AND firstName like $1")
List<User> findByFirstNameLike(String keyword);
This will generate something like the above query but with an extra where condition firstName like
Notice this method takes a keyword because there is a param placeholder defined $1.
Notice in the documentation it says
#{#n1ql.selectEntity} WHERE #{#n1ql.filter} AND test = $1
is equivalent to
SELECT #{#n1ql.fields} FROM #{#n1ql.bucket} WHERE
#{#n1ql.filter} AND test = $1
Now if you don't want to fetch all the data for user(s), you'll need to specify the fields being selected, read following links for more info
How to fetch a field from document using n1ql with spring-data-couchbase
https://docs.spring.io/spring-data/couchbase/docs/2.2.4.RELEASE/reference/html/#_dto_projections
I think you should try below query, that should resolve the issue to get fields based parameter you have sent as arguments.
Please refer blow query.
#Query("SELECT $1 FROM #{#n1q1.bucket} WHERE #{#n1ql.filter}")
List findByFirstName(String fieldName);
Here, bucket name resolve to the User entity and and n1ql.filter would be a default filter.

Simple query condition in sql

I have a Query - - < This Is a valid Query >
'SELECT *
FROM MyTable
WHERE city= ?
ORDER BY name ' [Keyname]
I am using this queried condition :: i am passing the Keyname as params from client to this sql query
This works & i get the required result BUT
If i pass nothing say null comes from client as param value for Keyname......... this query fails
how can i make the better query ... so that even if null comes ....
ORDER BY condition is satisfied
Or
R there other solution i need to look for
If so ... what is it ?
Hope i am clear
[EDIT]
CASE1:: for the url
http://54.218.73.244:7005/DescriptionSortedSearchRating/?Key=Pune
my told query satisfies::
But
http://54.218.73.244:7005/DescriptionSortedSearchRating/?Key=
my query fails, my sql query is expecting a Key for http://54.218.73.244:7005/DescriptionSortedSearchRating/ ..... if i pass nothing my query dosent get me a result..
.
what i am trying to see is even if i get nothing as key ORDER BY condition must be met ...
IF I PASS A KEY VALUE
IF I DONT PASS A KEY VALUE
You can clearly see i am not able to fetch results from database (Empty JSON)
This question doesn't have anything to do with MySQL. This is 100% your high level language. The null value the [Keyname] has is a null value in the language you're using to create the string that will be the final query.
The simplest solution will be not to assign null to your [Keyname] variable but rather an empty string.
You may use this:
ORDER BY name CASE WHEN Keyname IS NULL THEN '' ELSE CONCAT(',', Keyname) END
I am not sure whether the syntax is fine or not. But what I expect here to append empty string when Keyname is null and to append the Keyname with a comma (,). Please try it.
Other option is using function ISNULL
ISNULL(Keyname, '');

mongodb like concat mysql query

I have a table in Mysql where I have some D and C classes of IPs and I use this table to test if a request IP is in the database OR belongs to the C class like that:
select * from My_Table
where '192.168.1.12' LIKE CONCAT(ip, '%');
(where 192.168.1.12 is the request IP I am testing against my table)
In my Database, if I have the ip '192.168.1' in C format, I will get a match.
I was thinking about using MongoDB and have the same information in documents where each IP (either in C or D class format) is the _id (which is indexed by default).
How can I get it to work with MongoDB if regex would work just the opposite way? (if I had the C class beforehand)
If I split every request IP into a C class to check with regex like:
db.my_table.find(_id: '^/split_ip/')
I would have to check in my application again every result by iteration and I think that wouldn't be a good solution.
So, I am wondering if you have any advice or suggestion to give me.
You could use the $in operator to get all matching from a single query.
{ _id: {$in : [/^192.0.1.1/, /^194.1.1/ ] }}
Becuase you're using /^ option in regex, the index will be used.
Does that help?