Error "attribute parameter is not in hash ref" when using Perl DBI selectall_hashref - mysql

I'm trying to get my first select to work using selectall_hashref from the Perl DBI module. I've opened a connection to the database (MySQL) successfully. I'm getting an error when I execute the following:
$dbh->selectall_hashref('SELECT id FROM users WHERE login=?',undef,"myusername");
DBI::st=HASH(0x1505a60)->_prepare(...): attribute parameter 'myusername' is not a hash ref at /usr/lib/x86_64-linux-gnu/perl5/5.20/DBD/mysql.pm line 238.
My table should be able to support this query, it has an id column and login column for each user.
The examples I've found for selectall_hashref show the ? substitution parameter being passed as the third parameter. The DBI documentation says that the second and third arguments should be %attr and #bind_values but doesn't give much documentation about them or show working examples.
What is causing the error, and more importantly how do you actually use the %attr and #bind_values correctly?

If you want to store everything as an arrayref where each row is a hashref (which is what your comment seems to indicate), you can use the selectall_arrayref() method with the Slice attribute:
$dbh->selectall_arrayref('SELECT id FROM users WHERE login=?', {Slice => {}}, 'myusername');
It's a little weird, but here's how it works:
If $slice is a hash reference, fetchall_arrayref fetches each row as
a hash reference. If the $slice hash is empty then the keys in the
hashes have whatever name lettercase is returned by default. (See
"FetchHashKeyName" attribute.) If the $slice hash is not empty,
then it is used as a slice to select individual columns by name. The
values of the hash should be set to 1. The key names of the returned
hashes match the letter case of the names in the parameter hash,
regardless of the "FetchHashKeyName" attribute.
It's a good idea to set the FetchHashKeyName attribute on the database handle to make your hash key names consistent; I happen to like NAME_lc in my applications.

The methods expects key column as the second parameter and attributes ref is passed as third one. In the result it builds a hash with the specified column as a key. What you probably want, is selectall_arrayref:
$ dbh->selectall_arrayref('SELECT id FROM users WHERE login=?',undef,"myusername");

Related

Extract certain members of JSON array in MySQL

I have a table in MySQL where each row contains JSON returned from another system. The JSON will look something like:
[{"userId": "Dave"},{"userId": "Mary", "errorCode" : "DB Fail"}, {"userId": "Lorenza", "errorCode": "Web Error"}]
and I'm only interested in the members of the array containing an error code. In the future, these will be parsed into seperate rows of their own table, but in the meantime does MySql offer a way to extract only these with an errorCode?
I can use JSON_EXTRACT to extract the errorCodes only
JSON_EXTRACT(jsonData, '$[*].errorCode') AS errorCodes
but I really want the rest of the member (userId in the example above)
You could use the JSON_CONTAINS function to find the records with errorCode and then then use JSON_EXTRACT on those records. Put the JSON_CONTAINS in the where clause
I don't think you could do this with a single query without known boundaries of the number of elements, but you could use a stored procedure to run a loop.
e.g. each iteration runs LOCATE to find the position of "errorCode", and uses that location to run SUBSTR and/or SUBSTRING_INDEX to get the userid value and append it to another variable. The looped variable would just be the offset used in the LOCATE query.

AES_DECRYPT How do you check value is already decrypted in mysql

I want to decrypt fields in my database using sql on mysql but before I decrypt I need to check if the fields can be decrypted.
update customer
set name = aes_decrypt(from_base64(name), 'key')
If the provided key is wrong or data is invalid the name field will be set to null;
I have tried adding a where clause like below to make sure the field name is not already decrypted but this doesn't work all the time as the aes_decrypt can return null or garbage if the key is incorrect or data is invalid.
update customer
set name = aes_decrypt(from_base64(name), 'key')
where aes_decrypt(from_base64(name), 'key') is not null.
So how can I check if the returned value is null or "garbage"? Or what other approach is there?
From mysql doc: "it is possible for AES_DECRYPT() to return a non-NULL value (possibly garbage) if the input data or the key is invalid."
garbage example I get: w���� ��Y�'v��Y�m��_
Thanks
Instead of storing raw ciphertext, follow the lead of version 2 of Defuse Security's PHP encryption library:
Use authenticated encryption.
Use a version tag which tells what library was used as well as what version and any optional configuration information you need to add.
Make sure to calculate HMAC(tag || IV || ciphertext) instead of just HMAC(ciphertext).
Store the tag, IV/nonce, ciphertext, and MAC together; preferably as a hex- or base64-encoded string.
Then the question becomes "Do the first N bytes of the string evaluate to a known version tag of my encryption library"?

solr update with json causes 'error parsing json field. unexpected object_start'

I downloaded solr 4.6.1 and I am attempting to update the solr index using the following via command line:
curl http://localhost:8983/solr/update?commit=true -H 'Content-type:application/json' -d '
[{
"id" : "1",
"phoneNumber_ss": [{"foo_ss" : "bar"}]
}]
'
I am using the example schema.xml, which is why i used all the "_ss" fields.
The issue is that when I execute this I get the following response:
{"responseHeader":{"status":400,"QTime":1},"error":{"msg":"Error parsing JSON field value. Unexpected OBJECT_START","code":400}}
This seems to be related to the value specified for phoneNumber_ss field which is an array of objects. If I make the value into an array or an object it works fine, its only when it is an array of objects that the issue occurs.
Any help is much appreciated.
I don't think Solr support storing objects into a multivalued field. You can store it as a array of string. You might also store the object as a string and parse it in your application.
If you have such use case that you want to have all the objects from Solr only, you can follow the steps..
Create a multivalued field for your keys.
Maintain the same order of keys and create another multivalued field for values.
So, you can get the keys and values in same order in different fields. But in this approach you might face problems while updating those multivalued fields. You might want to look here
And finally, you are also missing some syntax in your update statement.
set – set or replace a particular value, or remove the value if null is specified as the new value
add – adds an additional value to a list
Check http://wiki.apache.org/solr/UpdateJSON

I want to extract the parameters of a url in mysql

I have in my database a column with the parameters value of an url. I want with an sql query to put those parameters in different columns. I give an example:
I have now a column named parameters with for example this value: pOrgNum=j11000&pLanguage=nl&source=homepage
now I want three columns: pOrgnum | pLanguage | source with the values of my parameters.
The problem is that I don't know the order of my parameters or the length of it, so I can't use for example substring(parameters,9,6) to extract the parameter pOrgnum. can someone help me please?
There's a MySQL UDF that you can use to do exactly this, which also handles decoding the params and handles most character encodings, etc.
https://github.com/StirlingMarketingGroup/mysql-get-url-param
Examples
select`get_url_param`('https://www.youtube.com/watch?v=KDszSrddGBc','v');
-- "KDszSrddGBc"
select`get_url_param`('watch?v=KDszSrddGBc','v');
-- "KDszSrddGBc"
select`get_url_param`('watch?v=KDszSrddGBc','x');
-- null
select`get_url_param`('https://www.google.com/search?q=cgo+uint32+to+pointer&rlz=1C1CHBF_enUS767US767&oq=cgo+uint32+to+pointer&aqs=chrome..69i57.12106j0j7&sourceid=chrome&ie=UTF-8','q');
-- "cgo uint32 to pointer"
select`get_url_param`('/search?q=Na%C3%AFvet%C3%A9&oq=Na%C3%AFvet%C3%A9','q');
-- "Naïveté"
Disclaimer, I am the author.
I achieved this by taking the right of the string after the search parameter, then the left of the resulting string before the first &.
This handles
if the parameter was the last in the url (so no "&" follows it)
if the parameter does not exist (returns blank)
varying lengths of the search string (provided you replace "utm_medium" everywhere)
This finds the value of "utm_medium" in a parameter named url:
IF(locate("utm_medium", url)=0, '', LEFT(RIGHT(url,length(url)-locate("utm_medium",url)-length("utm_medium")),IF(locate("&",RIGHT(url,length(url)-locate("utm_medium",url)-length("utm_medium")))=0,length(RIGHT(url,length(url)-locate("utm_medium",url)-length("utm_medium")+1)),locate("&",RIGHT(url,length(url)-locate("utm_medium",url)-length("utm_medium"))))-1)) utm_medium
To use, find and replace url with your field name, and utm_medium with your url parameter.
May be inefficient, but gets the job done, and couldn't find an easy answer elsewhere
Its code work in mysql:
SELECT substring_index(URL_FIELD,'\',-1) FROM DemoTable;

What is DC2Type array datatype in mysql

I have been working with Symfony2 and doctrine2 recently and have realized a peculiar datatype called DC2Type:array that certain Symfony2 Roles get saved as. To me it just looks like a serialized PHP array where a signifies the total number of elements, i is the array index.
The value looks like this:
a:15:{i:0;s:32:"ROLE_SONATA_USER_ADMIN_USER_EDIT";i:1;s:32:"ROLE_SONATA_USER_ADMIN_USER_LIST";i:2;s:34:"ROLE_SONATA_USER_ADMIN_USER_CREATE";i:3;s:32:"ROLE_SONATA_USER_ADMIN_USER_VIEW";i:4;s:34:"ROLE_SONATA_USER_ADMIN_USER_DELETE";i:5;s:36:"ROLE_SONATA_USER_ADMIN_USER_OPERATOR";i:6;s:34:"ROLE_SONATA_USER_ADMIN_USER_MASTER";i:7;s:33:"ROLE_SONATA_USER_ADMIN_GROUP_EDIT";i:8;s:33:"ROLE_SONATA_USER_ADMIN_GROUP_LIST";i:9;s:35:"ROLE_SONATA_USER_ADMIN_GROUP_CREATE";i:10;s:33:"ROLE_SONATA_USER_ADMIN_GROUP_VIEW";i:11;s:35:"ROLE_SONATA_USER_ADMIN_GROUP_DELETE";i:12;s:37:"ROLE_SONATA_USER_ADMIN_GROUP_OPERATOR";i:13;s:35:"ROLE_SONATA_USER_ADMIN_GROUP_MASTER";i:14;s:10:"ROLE_ADMIN";}
I want to know what this datatype is?
And what do the following identifier signifies:
s:
I have searched the internet but haven't got any useful data.
I also bumped upon this cookbook entry - http://readthedocs.org/docs/doctrine-orm/en/2.0.x/cookbook/mysql-enums.html but didn't figure out the origin.
This is not a data type. You might have noticed that the column type is LONGTEXT. DC2Type:array is a comment of the field.
Doctrine uses the field's comment as column's metadata storage place. Since Mysql does not allow you to store an array, Doctrine use DC2Type:array as comment in order to know how to unserialize the content.
Take a look at the link below.
https://github.com/doctrine/dbal/issues/1614
From the link you mentioned, you can see that the comment DC2Type:enumvisibility indicates that the content of the field is a flag, indicating that the record is visible or not. It is not a new data type at all. It should be considered an helper strategy in the database level. For Doctrine, it's a custom data type.
This is simply a string. Its format is a serialized PHP array. The s: refers to the size or length of each item value in the array.
e.g. s:32:"ROLE_SONATA_USER_ADMIN_USER_EDIT"
If you count the characters in the ROLE string, there are 32.
Hope this helps.