apex: lessons from the trenches odtug kaleidoscope, june 20, 2007 bill holtzman national air traffic...
TRANSCRIPT
ApEx: Lessons from the Trenches
ODTUG Kaleidoscope, June 20, 2007
Bill HoltzmanNational Air Traffic Controllers Association
June 21, 2007 ApEx Lessons from the
Trenches 2
NATCA
National Air Traffic Controllers Association
15,000 members 400 locations Employees of the Federal Aviation
Administration
June 21, 2007 ApEx Lessons from the
Trenches 3
Grievance
A complaint against the employer by an employee or the union
Over 200,000 active grievances Requirements akin to legal case
June 21, 2007 ApEx Lessons from the
Trenches 10
Manual report link – link || text
Manual link enables concatenation with plain text
<a href="f?p=104:8:10234501378364652310:::8:P8_DUP_GRID,P8_RETURN_PAGE,P8_ARTICLE:5880,32,0">06-ZDC-34</a><br><span style="font-size:8pt">123456</span>
June 21, 2007 ApEx Lessons from the
Trenches 11
Manual link - Javascript
Manual link with Javascript enables custom pop-ups'<a href="javascript:myPopUp(''f?p=&APP_ID.:9:' || :APP_SESSION ||
'::::P9_GRID:' || g.GRID || ''')" &F168_PRINT.>' || g.topic || '</a>' “Grievance Regarding<br>(View/Print)"
<a href="javascript:myPopUp('f?p=104:9:11001668615862681378 ::::P9_GRID:5581')" onMouseOver="return window.status='View this grievance for printing'" onMouseOut="return window.status =''">Article 34 Working Hours</a>
At runtime, this becomes:
June 21, 2007 ApEx Lessons from the
Trenches 12
Use of conditional ||
Decode and case enable conditional || with images, text
selectdecode(g.status_id, 1, decode(g.date_sub_2, null, trunc(g.u_action_2) - trunc(sysdate) || ' ' ||casewhen (g.u_action_2 - sysdate) > 7 then '<img src="#FLOW_IMAGES#greenN.gif">'when (g.u_action_2 - sysdate) > 3 then '<img src="#FLOW_IMAGES#yellowN.gif">'when (g.u_action_2 - sysdate) > 0 then '<img src="#FLOW_IMAGES#redN.gif">'else '<img src="#FLOW_IMAGES#past.gif" border="0">'end,to_char(g.date_sub_2, 'MM/DD/YY')), 'Closed') "DATE_SUB"from grievance g
June 21, 2007 ApEx Lessons from the
Trenches 13
SQL generated by PLSQL
SQL Report Region could not enable optional sorting of composite columns
Use of PLSQL-generated SQL enables finer control over the report source query, enhancing performance
June 21, 2007 ApEx Lessons from the
Trenches 14
Converting a report to PLSQL
declarep_sql varchar2(32767);beginp_sql := q'! select grid from grievance !';return p_sql;end;
Note: 10g quoting syntax
June 21, 2007 ApEx Lessons from the
Trenches 15
Adding conditions
declarep_sql varchar2(32767);beginp_sql := q'! select g.GRID, !';p_sql := p_sql || q'! '<a href="javascript$myPopUp(''f?p=&APP_ID.$9$' || $APP_SESSION || '$$$$P9_GRID$' || g.GRID || ''')" &F168_PRINT.>' || g.topic || '</a>' || gr_groupid(g.grid) "Topic“ !';p_sql := p_sql || q'! from GRIEVANCE g, gr_status_lookup p, gr_bu b where g.gr_status = 3 and g.status_id = p.id and g.bu_id = b.id (+) !';if :P35_FAANUM is not null thenp_sql := p_sql || q'! and lower(g.faanum) like '%' || lower($P35_FAANUM) || '%' !';end if;return replace(p_sql,'$',':');end;
June 21, 2007 ApEx Lessons from the
Trenches 16
Composite sortingdeclarep_sql varchar2(32767);beginp_sql := q'! select g.GRID, !';p_sql := p_sql || q'! '<a href="javascript$myPopUp(''f?p=&APP_ID.$9$' || $APP_SESSION || '$$$$P9_GRID$' || g.GRID || ''')" &F168_PRINT.>' || g.topic || '</a>' || gr_groupid(g.grid) "Topic" !';p_sql := p_sql || q'! from grievance g, gr_status_lookup p, gr_bu b where g.gr_status = 3 and g.status_id = p.id and g.bu_id = b.id (+) !';casewhen :P35_SORT = 1 then p_sql := p_sql || q'! order by trunc(g.reply_by_3), trunc(g.date_sub_3) nulls last !';when :P35_SORT = 2 then p_sql := p_sql || q'! order by trunc(g.date_sub_3), trunc(g.u_action_3) nulls last !';else null;end case;return replace(p_sql,'$',':');end;
June 21, 2007 ApEx Lessons from the
Trenches 20
Javascript on a Select ListPage Attributes
Page Item
June 21, 2007 ApEx Lessons from the
Trenches 21
Database-driven Javascriptdeclarep_java varchar2(4000);cursor c1 is select bu_id, bplate from gr_bu;beginp_java := 'function insertBP(p_region_id) {var p_bu_id = document.getElementById("P8_BU_ID").value;';for a1 in c1 loopp_java := p_java || chr(10) || 'if (p_bu_id == ' || a1.bu_id || ')' || chr(10) || 'document.getElementById("P8_BPLATE").value = "' || a1.bplate || '";';end loop;p_java := p_java || chr(10) || '}';:F168_BPLATE_JAVA := p_java;end;
June 21, 2007 ApEx Lessons from the
Trenches 22
Javascript resultfunction insertBP(p_region_id) { var p_bu_id = document.getElementById("P8_BU_ID").value;if (p_bu_id == 12)document.getElementById("P8_BPLATE").value = "This grievance is filed pursuant to the Interim agreements and 5 USC 7103 (a) (9). The Agency's actions constitute a violation of the Interim agreements between NATCA and the FAA, 5 USC Chapter 71, and all applicable laws, rules, regulations, and past practice. NOTE: Under protest, and as ordered by FAA management, this grievance is filed in accordance with the Imposed Working Rules (IWR).";if (p_bu_id == 13)document.getElementById("P8_BPLATE").value = "This grievance is filed pursuant to the Interim agreements and 5 USC 7103 (a) (9). "; }
June 21, 2007 ApEx Lessons from the
Trenches 23
Users upload and download documents associated with each grievance. The process is analogous to a legal case.
Custom tables for file storage
June 21, 2007 ApEx Lessons from the
Trenches 24
The custom tables are tied to individual grievances by the primary key GRID.
Upload/download tables
June 21, 2007 ApEx Lessons from the
Trenches 26
Upload: File size validation
A validation restricts the size of uploads.
June 21, 2007 ApEx Lessons from the
Trenches 27
Upload: File name validation
Javascript restricts the length of the file name. Application Express will not accept more than 78 characters.
June 21, 2007 ApEx Lessons from the
Trenches 29
Don’t forget! SQL> grant execute on download_my_file to public
Download link
June 21, 2007 ApEx Lessons from the
Trenches 30
Session state protection
http://www.abc.net/pls/htmldb/f?p=168:34:470931357178041727::NO:::&cs=3A70EA7DD614FA61411D4DCACB75E481C
June 21, 2007 ApEx Lessons from the
Trenches 32
Checksums in manual links
'<a href="javascript:myPopUp(''f?p=&APP_ID.:9:' || :APP_SESSION || '::::P9_GRID:' || g.GRID || ''')" &F168_PRINT.>' || g.topic || '</a>' "Topic"
'<a href="javascript:myPopUp(''' || htmldb_util.prepare_URL('f?p=&APP_ID.:9:' || :APP_SESSION || '::::P9_GRID:' || g.GRID) || ''')" &F168_PRINT.>' || g.topic || '</a>' "Topic"
Original SQL:
With session state protection:
June 21, 2007 ApEx Lessons from the
Trenches 34
Session state violation
Tampering with values in the URL produces this error message.
June 21, 2007 ApEx Lessons from the
Trenches 36
Automatic row processing
Automatic row processing includes optimistic locking.
But more advanced apps use manual processing.
June 21, 2007 ApEx Lessons from the
Trenches 37
Manual row processing
for c1 in (select * from grievance where grid = :P8_GRID) loopcurrent_state := utl_raw.cast_to_raw(dbms_obfuscation_toolkit.md5(input_string => c1.FAANUM||c1.GRIEVANT||c1.REP||c1.TOPIC||c1.ORAL));end loop;if current_state = :P8_CHECKSUM thenupdate grievance set faanum = :P8_FAANUM, rep = :P8_REP, topic = :P8_TOPIC, oral = :P8_ORAL where grid = :P8_GRID;:P8_RETURN_PAGE := 32;end case;else:P8_RETURN_PAGE := 39;end if;
:P8_CHECKSUM is calculated when the page is rendered. If it changes, the update does not execute.
June 21, 2007 ApEx Lessons from the
Trenches 38
Optimistic locking error
When the checksums do not agree, conditional processing prevents the update and conditional branching takes the user to this page.
June 21, 2007 ApEx Lessons from the
Trenches 39
Application level items
Page item names are visible in the HTML source
The names of application level items are not, making them more difficult to tamper with
June 21, 2007 ApEx Lessons from the
Trenches 40
Using application level itemsLOGIN PROCESS…casewhen p_sec_lev = 1 then:F134_HEADER := :F134_HEADER || 'FacRep Level';when p_sec_lev = 2 then:F134_HEADER := :F134_HEADER || 'RVP Level';elsenull;end case;
June 21, 2007 ApEx Lessons from the
Trenches 43
Internal message board
Build or borrow a message board application, customize it and integrate it into all of your apps for an internal message board/knowledge base.
June 21, 2007 ApEx Lessons from the
Trenches 45
Thank you!
For more information:Bill [email protected]