Store a complex hash in Apache::Sessions:MySQL session - mysql

So, I'm trying to store a decoded JSON object into a tied apache session. This is my code:
$url="https://apilink";
$content = get($url);
die "Can't Get $url" if (! defined $content);
$jsonOb = decode_json($content);
%aprecords = %$jsonOb;
#Push the jsonOb in the session
$session{apirecords} = \%aprecords ;
$session{apirecords} does not store the %aprecords reference. Although, when I substitute the statement to $session{apirecords} = \%jsonOb ; , it stores apirecords in the sessions table but the reference to %jsonOb has no values in it.
PS:
I have tried the following and none of them seem to work:
1) $session{apirecords} = \%$jsonOb ;
2) $session{apirecords} = { %aprecords } ;
JSON object is perfectly well structured.
Code for tying a session:
tie %session, "Apache::Session::MySQL", $sessionID,
{
Handle => $dbObject,
LockHandle => $dbObject,
TableName => 'sessions',
};
#If a session ID doesn't exist, create a new session and get new session ID
if (!defined ($sessionID)){
$sessionID = $session{_session_id};
$session{count}=0;
}
A helping hand would be much much appreciated!
JSON Sample: https://jsonblob.com/feed3bba-f1cd-11e8-9450-2904e8ecf943

As pointed out by GMB. The blob size(64 KB) wasn't big enough for the JSON object.
The solution is to change blob datatype to mediumblob .

Related

Using Mojo::UserAgent and accessing the JSON in response?

How can I get access to JSON in a mojo response?
$txn = $ua->post( $url, $headers, json => {json} )
What's the way to get the JSON response from the txn?
I have several examples in my book Mojolicious Web Clients, but here's the deal.
When you make a request, you get back a transaction object:
my $ua = Mojo::UserAgent->new;
my $tx = $ua->post( ... );
The transaction object has both the request and response (a major feature that distinguishes Mojo from LWP and even other user agent libraries in other languages). To get the response, you can use the res or result methods. The result dies for you if it couldn't make the request because a connection error occurred (ENONETWORK):
my $res = $tx->result;
Once you have the response, there are various things you can do (and these are in the SYNOPIS section of the Mojo::UserAgent. If you want to save the result to a file, that's easy:
$res->save_to( 'some.json' );
You can turn the content into a DOM and extract parts of HTML or XML:
my #links = $res->dom->find( 'a' )->map( attr => 'href' )->each;
For a JSON response, you can extract the contents into a Perl data structure:
my $data_structure = $res->json;
However, if you wanted the raw JSON (the raw, undecoded content body), that's the message body of the request. Think of that like the literal, unfiltered text:
use Mojo::JSON qw(decode_json);
my $raw = $res->body;
my $data_strcuture = decode_json( $raw );
Since this is the response object, Mojo::Message and Mojo::Message::Response show you what you can do.
Here's a complete test program:
#!perl
use v5.12;
use warnings;
use utf8;
use Mojo::JSON qw(decode_json);
use Mojo::UserAgent;
use Mojo::Util qw(dumper);
my $ua = Mojo::UserAgent->new;
my $tx = $ua->get(
'http://httpbin.org/get',
form => {
name => 'My résumé'
},
);
die "Unsuccessful request"
unless eval { $tx->result->is_success };
my $data_structure = $tx->res->json;
say dumper( $data_structure );
my $raw = $tx->res->body;
say $raw;
my $decoded = decode_json( $raw );
say dumper( $decoded );
I was able to get access to this data like this,
my $api_order = $tx_cart->result->json->{data};
It's in result not in body.

Using Dancer2::Plugin::DBIC to pull values from database

I have a webapp where a user can log in and see a dashboard with some data. I'm using APIary for mock data and in my Postgres Database each of my users have an ID. These ID's are also used in the APIary JSON file with relevant information.
I'm using REST::Client and JSON to connect so for example the url for the user's dashboard is: "/user/dashboard/12345" (in Apiary)
and in the database there is a user with the ID "12345".
How can I make it so when the user logs in, their ID is used to pull the data that is relevant to them? (/user/dashboard/{id})? Any documentation or advice would be much appreciated!
The docs of Dancer2::Plugin::Auth::Extensible are showing one part of what you need to do already. In short, save the user ID in the session. I took part of code in the doc and added the session.
post '/login' => sub {
my ($success, $realm) = authenticate_user(
params->{username}, params->{password}
);
if ($success) {
# we are saving your user ID to the session here
session logged_in_user => params->{username};
session logged_in_user_realm => $realm;
} else {
# authentication failed
}
};
get '/dashboard' => sub {
my $client = REST::Client->new();
# ... and now we use the user ID from the session to get the
# from the webservice
$client->GET( $apiary . '/user/dashboard/' . session('logged_in_user') );
my $data = $client->responseContent();
# do stuff with $data
};
For those who want to know what I ended up doing:
Dancer2::Plugin::Auth::Extensible has
$user = logged_in_user();
When I printed this it showed me a hash of all the values that user had in the database including the additional ID I had. So I accessed the id with
my $user_id = $user->{user_id};
And appended $user_id to the end of the url!

EntityMetadataWrapperException: Invalid data value given when setting file field

Cannot set file_field in field_collection
Has node $order and field_collection called field_blueprints:
<?php
$entity_type = "field_collection_item";
$blueprint_obj = entity_create($entity_type, array('field_name' => "field_blueprints") );
$blueprint_obj->setHostEntity('node', $order);
$blueprint_entity = entity_metadata_wrapper($entity_type, $blueprint_obj);
date_default_timezone_set("UTC");
$blueprint_entity->field_blueprint_file->file->set((array)$file);
$blueprint_entity->field_blueprint_comment = (string) $file->filename;
$blueprint_obj->save();
node_save($order);
And this code throws error:
EntityMetadataWrapperException: Invalid data value given. Be sure it matches the required data type and format. in EntityDrupalWrapper->set() (line 736 of sites//all/modules/entity/includes/entity.wrapper.inc).
I have also tried:
$blueprint_entity->field_blueprint_file->set((array)$file)
$blueprint_entity->field_blueprint_file->set(array('fid'=>$file->fid))
You need to either pass the file object or an array with a fid key to make it work.
So it's either:
// Single value field
$blueprint_entity->field_blueprint_file = array('fid' => $file->fid);
// Multi-value field
$blueprint_entity->field_blueprint_file[] = array('fid' => $file->fid);
or:
// Single value field
$blueprint_entity->field_blueprint_file = $file;
// Multi-value field
$blueprint_entity->field_blueprint_file[] = $file;
Here is complete example using value(), set() and save() from Entity metadata wrappers page:
<?php
$containing_node = node_load($nid);
$w_containing_node = entity_metadata_wrapper('node', $containing_node);
// Load the file object in any way
$file_obj = file_load($fid);
$w_containing_node->field_attachment_content->file->set( $file_obj );
// ..or pass an array with the fid
$w_containing_node->field_attachment_content->set( array('fid' => $fid) );
$w_containing_node->save();
?>
Also when dealing with multiple-valued field (cardinality > 1), make sure you wrap it into extra array.

RedBean PHP credit card number issue

I have started using Redbean PHP recently. So I am not much aware of how it deals things.
Until now I love how simple it is making things for me. But I have ran into quite an issue today. I need to store credit card numbers into a table. But as soon as I store the bean, the card number gets changed into a float(decimal) kind of value.
'1234123412341234' is getting stored as '1.234123412341234e15'
The datatype is 'double' created by redbean, but I gave as a string. This is kind of weird for me I am not much of an expert in either SQL or PHP. Is there a way to override how redbean creates table. So someone please help me. Am I missing something here. The following is my corresponding code and the framework used is Codeigniter.
Data Variable
$data = array(
'card_name' => 'Shiva Kumar Avula',
'card_no' => '1234123412341234',
'card_issuer' => 'Visa',
'card_cvv' => '123',
'card_exp_month' => 12,
'card_exp_year' => 2020
);
$card = $this->card_model->create_card($data, TRUE); // Making it primary
Model Function
public function create_card($data, $is_primary = FALSE)
{
$card = R::dispense('card');
$card->name = $data['card_name'];
$card->number = $data['card_no'];
$card->issuer = $data['card_issuer'];
$card->cvv = $data['card_cvv'];
$card->exp_month = $data['card_exp_month'];
$card->exp_year = $data['card_exp_year'];
$card->is_primary = $is_primary;
$card->is_verified = 0;
$card->ts_created = $this->ts_sql;
$card->ts_modified = $this->ts_sql;
$id = R::store($card);
}
Snapshot of my output in phpmyadmin,
Snapshot that shows the datatype,
You can set the beans meta property for number to string.
$card->setMeta("cast.number", "string");
This will save any values of $card->number as varchar.
See RedBean Internals for more information.

What is the best means to get the unique hash data into a JSON object without using an array when cycling through a DB Dataset?

I need to get the data into a JSON object but because I'm using the %data hash and it has the same address I'm getting the same data repeatedly in my JSON object.
This is the code that produces the JSON.
while (my ($orderID, $possessorName, $itemDescription, $...) = $sth->fetchrow_array)
{
%data = (orderID => $orderID, possessorName => $possessorName, itemDescription => $itemDescription,...);
$query_results{"job$index"} = {"data" => \%data};
$index++;
}
return $json_obj->pretty->encode(\%query_results, {ascii => 1, pretty => 1});
The problem is that the last item in my data set is masking all the previous items so I end up with one large JSON of the same exact data. I could use an array of hashes I suppose but this seems really messy and sloppy. How do I write the cleanest code to get my data? If an array of hashes is the best way to go please let me know and I'll do it. I all ready know how or can figure it out on my own.
What happens when you try:
my $index = 0;
my %query_results;
while (my ($orderID, $possessorName, $itemDescription, $...) = $sth->fetchrow_array) {
my %data = (orderID => $orderID, possessorName => $possessorName, itemDescription => $itemDescription,...);
$query_results{"job$index"}{'data'} = \%data;
$index++;
}
Previously, you used a %data hash declared in an outside scope; or worse, you didn't use strict; use warnings so %data was in fact an implicit global. Now, we declare the %data inside the loop which makes all the hashes distinct.
You could also copy the hash into a new hashref by {%data}.
That said, you don't even need that variable:
$query_results{"job$index"}{data} = {
# anonymous hashref here
orderID => $orderId,
possessorName => $possessorName,
itemDescription => ...
};