StoredHash::Tutorial - Practical use-case scenarios for StoredHash
Using automatic DB backed assigned numbering for primary keys is a common practice. When using this convention use StoredHash construction parameter 'autoid' set to true value:
my $shp = StoredHash->new(.... , 'autoid' => 1);
At the DB backend these columns are typically defined:
Refer to the latest manuals of respective databases for most recent and accurate information.
StoredHash::ARS does not require primary key ('pkey') or ('autoid') as these are pre-determined by ARS/Remedy conventions.
A simple example of a HTML form processing, assuming the db attribute names were used 1:1 on the HTML form:
sub handle_store {
my ($cgi) = @_;
my $h = $cgi->Vars();
delete($h->{'extrakey'}); # Or any other keys that do not belong to DB
my $id = $shp->insert($h);
print("<p>Your entry was stored successfully (By ID: $id)\n</p>");
my $hfromdb = $shp->load([$id]);
return(0);
}
Note: multiple values on a single key are encoded to null-byte delimited serial form by CGI.pm, above example assumes single value per key. On multi-valued keys you'd likely hit problems.
Lets use CGI.pm module for its ubiquitouness. You did use content type other than "application/x-www-form-urlencoded" - right ? Because sender is AJAX client, lets respond with
use JSON::XS;
sub handle_store_json {
my ($cgi) = @_;
my $reqtype = $cgi->content_type();
my $reqmeth = $cgi->request_method();
if ($reqtype eq 'application/x-www-form-urlencoded') {die("Not valid POST content-type");}
if ($reqmeth ne 'POST') {die("Only POST allowed for JSON/REST");}
# Grab JSON from Body of HTTP Request
my $msg = decode_json($cgi->param('POSTDATA'));
if ($msg->{'type'} ne 'store') {die("Not valid message");}
my $h = $msg->{'entry'};
my $resp = {'status' => 'OK'};
my $id = $shp->insert($h);
if (!$id) {@$resp{'status','msg'} = ('FAIL', "Failed to Store Entry");}
print(encode_json($resp));
return(0);
}
my $shps = StoredHash->new('table' => 'Products', 'pkey' => ['ProdID'],
'dbh' => $dbh, 'autoid' => 1);
my $shpt = StoredHash->new('table' => 'Products', 'pkey' => ['ProdID'],
'dbh' => $dbh, 'autoid' => 1);
# Verify Schema sync (No strict type check, but if names match
# it is likely no-one messed up the schema
my $cols_s = $shps->cols();
my $cols_t = $shpt->cols();
# If target has superset of cols, replication would still (likely) work,
# But this is just an example of possible validation assisted by StoredHash
if (join('', @cols_s) ne join('', @cols_t)) {die("Schema Mismatch");}
# Load from SOURCE ($shps)
my $arr = $shps->loadset(); # Load ALL
# Replicate to target ($shpt)
map({
if ($shpt->exists($_)) {$shpt->update($_, [$_->{'ProdID'}]);}
else {$shpt->insert($_);}
} @$arr);
# New API allows you to use with single persister with long lifetime by passing $dbh # at the insert / update / exists methodcall
#my $arr = $shps->loadset('dbh' => $dbh_src); #'dbh' => $dbh_tgt
TODO: NoIDUpdate with autoid
# Method for getting values
sub onclick_save {
my ($widget, $udata) = @_;
my %uivals = (};
# Use GTKBuilder / GTK widget methods to access form values
$uivals{'fullname'} = $builder->get_object("fullname")->get_text();
# ...
my $ok = $shp->insert(\%uivals);
# Run dialog / Show in status
$dialog->run();
}
#=head1 Replacing Stored Procedures with StoredHash # #Vision the following StoredProcedure stored in DB: # # INSERT INTO ... # #And its replacement using StoredHash # # my $id = $shp->insert($e); # # #Do you still want to maintain the Stored Procedure ?