SlideShare une entreprise Scribd logo
1  sur  22
David Noe
Orange County Library System
dnoe@ocls.info
Automating Custom Patron Notices
and Messages Using SQL
• Metropolitan public library
• Main downtown library and 14 branches
• Serving > 1,000,000 Orange County Residents
• > 1.7 million items
• ~ 0.5 million checkouts a month
• ~10% of that are requests delivered
• ~350 employees
• Annual budget totals approximately $35.3 million
• Migrated to Sierra in late 2012
PROBLEMS:
• Delivered notices are clunky
Browser email Mobile
PROBLEMS:
• Delivered notices are clunky
• Customizing delivered notices?
– iReport (which is being replaced by something else?)
– Java
– Notice Data Libraries
PROBLEMS:
• Delivered notices are clunky
• Customizing delivered notices?
– iReport (which is being replaced by something else?)
– Java
– Notice Data Libraries
• Limited notices delivered
– Holds expiration alert
– Welcome messages
– Due date alerts
– Fine alerts
EXAMPLE CUSTOM NOTICE WE SENT BEFORE SQL ACCESS:
SOLUTION:
Create our own email notices leveraging in-house expertise.
LANGUAGE
•Perl
•Python
•VB
•PHP
PHP
LANGUAGE
•Perl
•Python
•VB
•PHP
•Whatever you got
BASIC DATA FLOW
RESOURCES
PHP
MySQL
WELCOME MESSAGE
<PHP?
$dbp = pg_connect("host=192.168.xxx.xxx port=1032 dbname=iii user=xxx password=xxx");
$dbm = mysql_pconnect('192.168.xxx.xxx','xxxx','xxxx');
$items = array();
$html = file_get_contents('/home/xxx/scripts/Templates/welcome_email.html');
$htmls = '';
$nl = "rn";
$q = "
SELECT
svn.patron_record_id as prid, svv.field_content as em, svn.last_name as ln, svn.first_name as fn
FROM sierra_view.patron_record svp
LEFT JOIN sierra_view.record_metadata svm
ON svp.id=svm.id
LEFT JOIN sierra_view.varfield svv
ON svp.record_id = svv.record_id
LEFT JOIN sierra_view.patron_record_fullname svn
ON svp.record_id = svn.patron_record_id
WHERE date(svm.creation_date_gmt) = current_date -15
AND svm.record_type_code='p'
AND svp.mblock_code = '-'
AND svp.ptype_code < '2'
AND svv.varfield_type_code = 'z';
";
$r = pg_query($dbp,$q); ...
WELCOME MESSAGE (only touching on core concepts)
if ($r) {
while ($row = pg_fetch_assoc($r)) {
$pid = $row['prid'];
$ln = ucwords(strtolower($row['ln']));
$fn = ucwords(strtolower($row['fn']));
$em = trim($row['em']);
if (@!$items[$em]) {
$items[$em][0][0] = $ln;
$items[$em][0][1] = $fn;
$items[$em][0][2] = $pid;
} else {
array_push($items[$em],array($ln,$fn,$pid));
}
}
} ...
WELCOME MESSAGE (seriously, do not attempt to read all of this)
foreach ($items as $h => $a) {
echo "rn<$h> "".$items[$h][0][0]." ".$items[$h][0][1]." ".$items[$h][0][2]."" rn";
$pname = $items[$h][0][1]." ".$items[$h][0][0];
$prid = $items[$h][0][2];
$em = trim($h);
$to = $h;
$subject = 'The Coolest Card In Town';
$headers = "From: <donotreply@ocls.info> "Orange County Library System"rn";
$headers .= "MIME-Version: 1.0rn";
$headers .= "Content-Type: text/html; charset=ISO-8859-1rn"; ...
WELCOME MESSAGE (not my code, so it takes me half an hour)
if ($dbm) {
$s = "insert into statistics.welcomenotices(pid,em,ts) values ('".$prid."','".$em."',now());";
$r = mysql_query($s,$dbm);
echo "logging data rn";
} else {
echo "no connection to mysql rn";
}
if (preg_match('/^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+.[a-zA-Z0-9-.]+$/',$em) == 1) {
$htmls = str_replace('<!-- PATRON -->',$pname,$html);
mail($to,$subject,$htmls,$headers);
usleep(1500000);
}
}
?>
WELCOME MESSAGE (I may try to post some of our code later)
DUE DATE ALERT
SELECT
svc.patron_record_id as pid,
svp.first_name as fn,
svp.last_name as ln,
svv.field_content as email,
svb.best_title as title
FROM sierra_view.checkout svc
LEFT JOIN sierra_view.patron_record_fullname svp
ON svc.patron_record_id = svp.patron_record_id
LEFT JOIN sierra_view.varfield svv
ON svp.patron_record_id = svv.record_id
LEFT JOIN sierra_view.item_record_property svi
ON svi.item_record_id = svc.item_record_id
LEFT JOIN sierra_view.bib_record_item_record_link svl
ON svl.item_record_id = svi.item_record_id
LEFT JOIN sierra_view.bib_record_property svb
ON svl.bib_record_id=svb.bib_record_id
WHERE
date(svc.due_gmt) = current_date
AND svv.varfield_type_code = 'z'
ORDER BY svp.patron_record_id;
HOLDS EXPIRATION ALERT
SELECT
svh.patron_record_id as pid,
date_trunc('day',svh.expires_gmt) as exp,
svp.last_name as ln,
svp.first_name as fn,
sv1.field_content as email,
sv2.field_content as title
FROM
sierra_view.hold svh
LEFT JOIN sierra_view.patron_record_fullname svp
ON (svh.patron_record_id = svp.patron_record_id)
JOIN sierra_view.varfield sv1
ON (svh.patron_record_id = sv1.record_id
AND sv1.varfield_type_code = 'z')
LEFT JOIN sierra_view.bib_record_item_record_link bil
ON (svh.record_id = bil.item_record_id)
LEFT JOIN sierra_view.varfield sv2
ON ((svh.record_id = sv2.record_id
OR bil.bib_record_id = sv2.record_id)
AND sv2.varfield_type_code = 't')
WHERE
DATE(svh.expires_gmt) > DATE (now() + interval '7days')
AND DATE(svh.expires_gmt) < DATE (now() + interval '14days')
ORDER BY svh.patron_record_id asc, exp asc;
FINE ALERT
FURTURE PLANS
• Courtesy notices
• More personalized welcome notices
• Requests filled (held items delivery)
• Internal statistics
Fin.

Contenu connexe

Similaire à Automating Custom Notices and Messages Using SQL

PHP Database Programming Basics -- Northeast PHP
PHP Database Programming Basics -- Northeast PHPPHP Database Programming Basics -- Northeast PHP
PHP Database Programming Basics -- Northeast PHPDave Stokes
 
iOS Dev Happy Hour Realm - Feb 2021
iOS Dev Happy Hour Realm - Feb 2021iOS Dev Happy Hour Realm - Feb 2021
iOS Dev Happy Hour Realm - Feb 2021Jason Flax
 
Practical Ruby Projects with MongoDB - Ruby Kaigi 2010
Practical Ruby Projects with MongoDB - Ruby Kaigi 2010Practical Ruby Projects with MongoDB - Ruby Kaigi 2010
Practical Ruby Projects with MongoDB - Ruby Kaigi 2010Alex Sharp
 
SDEC2011 NoSQL Data modelling
SDEC2011 NoSQL Data modellingSDEC2011 NoSQL Data modelling
SDEC2011 NoSQL Data modellingKorea Sdec
 
Modern Web Technologies — Jerusalem Web Professionals, January 2011
Modern Web Technologies — Jerusalem Web Professionals, January 2011Modern Web Technologies — Jerusalem Web Professionals, January 2011
Modern Web Technologies — Jerusalem Web Professionals, January 2011Reuven Lerner
 
Modern Web technologies (and why you should care): Megacomm, Jerusalem, Febru...
Modern Web technologies (and why you should care): Megacomm, Jerusalem, Febru...Modern Web technologies (and why you should care): Megacomm, Jerusalem, Febru...
Modern Web technologies (and why you should care): Megacomm, Jerusalem, Febru...Reuven Lerner
 
Redis for your boss 2.0
Redis for your boss 2.0Redis for your boss 2.0
Redis for your boss 2.0Elena Kolevska
 
My Sql And Search At Craigslist
My Sql And Search At CraigslistMy Sql And Search At Craigslist
My Sql And Search At CraigslistMySQLConference
 
Agg framework selectgroup feb2015 v2
Agg framework selectgroup feb2015 v2Agg framework selectgroup feb2015 v2
Agg framework selectgroup feb2015 v2MongoDB
 
The Transparent Web: Bridging the Chasm in Web Development
The Transparent Web: Bridging the Chasm in Web DevelopmentThe Transparent Web: Bridging the Chasm in Web Development
The Transparent Web: Bridging the Chasm in Web Developmenttwopoint718
 
Php course-in-navimumbai
Php course-in-navimumbaiPhp course-in-navimumbai
Php course-in-navimumbaivibrantuser
 
Locality sensitive hashing
Locality sensitive hashingLocality sensitive hashing
Locality sensitive hashingSEMINARGROOT
 
Scaling php applications with redis
Scaling php applications with redisScaling php applications with redis
Scaling php applications with redisjimbojsb
 
MongoDB .local Chicago 2019: REST-less Mobile Apps: Why Offline-first & Sync ...
MongoDB .local Chicago 2019: REST-less Mobile Apps: Why Offline-first & Sync ...MongoDB .local Chicago 2019: REST-less Mobile Apps: Why Offline-first & Sync ...
MongoDB .local Chicago 2019: REST-less Mobile Apps: Why Offline-first & Sync ...MongoDB
 
Electron, databases, and RxDB
Electron, databases, and RxDBElectron, databases, and RxDB
Electron, databases, and RxDBBen Gotow
 

Similaire à Automating Custom Notices and Messages Using SQL (19)

Php introduction
Php introductionPhp introduction
Php introduction
 
Network programming
Network programmingNetwork programming
Network programming
 
PHP Database Programming Basics -- Northeast PHP
PHP Database Programming Basics -- Northeast PHPPHP Database Programming Basics -- Northeast PHP
PHP Database Programming Basics -- Northeast PHP
 
iOS Dev Happy Hour Realm - Feb 2021
iOS Dev Happy Hour Realm - Feb 2021iOS Dev Happy Hour Realm - Feb 2021
iOS Dev Happy Hour Realm - Feb 2021
 
Practical Ruby Projects with MongoDB - Ruby Kaigi 2010
Practical Ruby Projects with MongoDB - Ruby Kaigi 2010Practical Ruby Projects with MongoDB - Ruby Kaigi 2010
Practical Ruby Projects with MongoDB - Ruby Kaigi 2010
 
SDEC2011 NoSQL Data modelling
SDEC2011 NoSQL Data modellingSDEC2011 NoSQL Data modelling
SDEC2011 NoSQL Data modelling
 
Lua pitfalls
Lua pitfallsLua pitfalls
Lua pitfalls
 
Revenge of the ORMs
Revenge of the ORMsRevenge of the ORMs
Revenge of the ORMs
 
Modern Web Technologies — Jerusalem Web Professionals, January 2011
Modern Web Technologies — Jerusalem Web Professionals, January 2011Modern Web Technologies — Jerusalem Web Professionals, January 2011
Modern Web Technologies — Jerusalem Web Professionals, January 2011
 
Modern Web technologies (and why you should care): Megacomm, Jerusalem, Febru...
Modern Web technologies (and why you should care): Megacomm, Jerusalem, Febru...Modern Web technologies (and why you should care): Megacomm, Jerusalem, Febru...
Modern Web technologies (and why you should care): Megacomm, Jerusalem, Febru...
 
Redis for your boss 2.0
Redis for your boss 2.0Redis for your boss 2.0
Redis for your boss 2.0
 
My Sql And Search At Craigslist
My Sql And Search At CraigslistMy Sql And Search At Craigslist
My Sql And Search At Craigslist
 
Agg framework selectgroup feb2015 v2
Agg framework selectgroup feb2015 v2Agg framework selectgroup feb2015 v2
Agg framework selectgroup feb2015 v2
 
The Transparent Web: Bridging the Chasm in Web Development
The Transparent Web: Bridging the Chasm in Web DevelopmentThe Transparent Web: Bridging the Chasm in Web Development
The Transparent Web: Bridging the Chasm in Web Development
 
Php course-in-navimumbai
Php course-in-navimumbaiPhp course-in-navimumbai
Php course-in-navimumbai
 
Locality sensitive hashing
Locality sensitive hashingLocality sensitive hashing
Locality sensitive hashing
 
Scaling php applications with redis
Scaling php applications with redisScaling php applications with redis
Scaling php applications with redis
 
MongoDB .local Chicago 2019: REST-less Mobile Apps: Why Offline-first & Sync ...
MongoDB .local Chicago 2019: REST-less Mobile Apps: Why Offline-first & Sync ...MongoDB .local Chicago 2019: REST-less Mobile Apps: Why Offline-first & Sync ...
MongoDB .local Chicago 2019: REST-less Mobile Apps: Why Offline-first & Sync ...
 
Electron, databases, and RxDB
Electron, databases, and RxDBElectron, databases, and RxDB
Electron, databases, and RxDB
 

Automating Custom Notices and Messages Using SQL

  • 1. David Noe Orange County Library System dnoe@ocls.info Automating Custom Patron Notices and Messages Using SQL
  • 2. • Metropolitan public library • Main downtown library and 14 branches • Serving > 1,000,000 Orange County Residents • > 1.7 million items • ~ 0.5 million checkouts a month • ~10% of that are requests delivered • ~350 employees • Annual budget totals approximately $35.3 million • Migrated to Sierra in late 2012
  • 3. PROBLEMS: • Delivered notices are clunky Browser email Mobile
  • 4. PROBLEMS: • Delivered notices are clunky • Customizing delivered notices? – iReport (which is being replaced by something else?) – Java – Notice Data Libraries
  • 5. PROBLEMS: • Delivered notices are clunky • Customizing delivered notices? – iReport (which is being replaced by something else?) – Java – Notice Data Libraries • Limited notices delivered – Holds expiration alert – Welcome messages – Due date alerts – Fine alerts
  • 6. EXAMPLE CUSTOM NOTICE WE SENT BEFORE SQL ACCESS:
  • 7. SOLUTION: Create our own email notices leveraging in-house expertise.
  • 9. PHP
  • 14. <PHP? $dbp = pg_connect("host=192.168.xxx.xxx port=1032 dbname=iii user=xxx password=xxx"); $dbm = mysql_pconnect('192.168.xxx.xxx','xxxx','xxxx'); $items = array(); $html = file_get_contents('/home/xxx/scripts/Templates/welcome_email.html'); $htmls = ''; $nl = "rn"; $q = " SELECT svn.patron_record_id as prid, svv.field_content as em, svn.last_name as ln, svn.first_name as fn FROM sierra_view.patron_record svp LEFT JOIN sierra_view.record_metadata svm ON svp.id=svm.id LEFT JOIN sierra_view.varfield svv ON svp.record_id = svv.record_id LEFT JOIN sierra_view.patron_record_fullname svn ON svp.record_id = svn.patron_record_id WHERE date(svm.creation_date_gmt) = current_date -15 AND svm.record_type_code='p' AND svp.mblock_code = '-' AND svp.ptype_code < '2' AND svv.varfield_type_code = 'z'; "; $r = pg_query($dbp,$q); ... WELCOME MESSAGE (only touching on core concepts)
  • 15. if ($r) { while ($row = pg_fetch_assoc($r)) { $pid = $row['prid']; $ln = ucwords(strtolower($row['ln'])); $fn = ucwords(strtolower($row['fn'])); $em = trim($row['em']); if (@!$items[$em]) { $items[$em][0][0] = $ln; $items[$em][0][1] = $fn; $items[$em][0][2] = $pid; } else { array_push($items[$em],array($ln,$fn,$pid)); } } } ... WELCOME MESSAGE (seriously, do not attempt to read all of this)
  • 16. foreach ($items as $h => $a) { echo "rn<$h> "".$items[$h][0][0]." ".$items[$h][0][1]." ".$items[$h][0][2]."" rn"; $pname = $items[$h][0][1]." ".$items[$h][0][0]; $prid = $items[$h][0][2]; $em = trim($h); $to = $h; $subject = 'The Coolest Card In Town'; $headers = "From: <donotreply@ocls.info> "Orange County Library System"rn"; $headers .= "MIME-Version: 1.0rn"; $headers .= "Content-Type: text/html; charset=ISO-8859-1rn"; ... WELCOME MESSAGE (not my code, so it takes me half an hour)
  • 17. if ($dbm) { $s = "insert into statistics.welcomenotices(pid,em,ts) values ('".$prid."','".$em."',now());"; $r = mysql_query($s,$dbm); echo "logging data rn"; } else { echo "no connection to mysql rn"; } if (preg_match('/^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+.[a-zA-Z0-9-.]+$/',$em) == 1) { $htmls = str_replace('<!-- PATRON -->',$pname,$html); mail($to,$subject,$htmls,$headers); usleep(1500000); } } ?> WELCOME MESSAGE (I may try to post some of our code later)
  • 18. DUE DATE ALERT SELECT svc.patron_record_id as pid, svp.first_name as fn, svp.last_name as ln, svv.field_content as email, svb.best_title as title FROM sierra_view.checkout svc LEFT JOIN sierra_view.patron_record_fullname svp ON svc.patron_record_id = svp.patron_record_id LEFT JOIN sierra_view.varfield svv ON svp.patron_record_id = svv.record_id LEFT JOIN sierra_view.item_record_property svi ON svi.item_record_id = svc.item_record_id LEFT JOIN sierra_view.bib_record_item_record_link svl ON svl.item_record_id = svi.item_record_id LEFT JOIN sierra_view.bib_record_property svb ON svl.bib_record_id=svb.bib_record_id WHERE date(svc.due_gmt) = current_date AND svv.varfield_type_code = 'z' ORDER BY svp.patron_record_id;
  • 19. HOLDS EXPIRATION ALERT SELECT svh.patron_record_id as pid, date_trunc('day',svh.expires_gmt) as exp, svp.last_name as ln, svp.first_name as fn, sv1.field_content as email, sv2.field_content as title FROM sierra_view.hold svh LEFT JOIN sierra_view.patron_record_fullname svp ON (svh.patron_record_id = svp.patron_record_id) JOIN sierra_view.varfield sv1 ON (svh.patron_record_id = sv1.record_id AND sv1.varfield_type_code = 'z') LEFT JOIN sierra_view.bib_record_item_record_link bil ON (svh.record_id = bil.item_record_id) LEFT JOIN sierra_view.varfield sv2 ON ((svh.record_id = sv2.record_id OR bil.bib_record_id = sv2.record_id) AND sv2.varfield_type_code = 't') WHERE DATE(svh.expires_gmt) > DATE (now() + interval '7days') AND DATE(svh.expires_gmt) < DATE (now() + interval '14days') ORDER BY svh.patron_record_id asc, exp asc;
  • 21. FURTURE PLANS • Courtesy notices • More personalized welcome notices • Requests filled (held items delivery) • Internal statistics
  • 22. Fin.