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 ?