apex: lessons from the trenches odtug kaleidoscope, june 20, 2007 bill holtzman national air traffic...

45
ApEx: Lessons from the Trenches ODTUG Kaleidoscope, June 20, 2007 Bill Holtzman National Air Traffic Controllers Association

Upload: brianna-hensley

Post on 30-Dec-2015

213 views

Category:

Documents


0 download

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 4

G.A.T.S.

June 21, 2007 ApEx Lessons from the

Trenches 5

Wizards

June 21, 2007 ApEx Lessons from the

Trenches 6

Graphical query builder

June 21, 2007 ApEx Lessons from the

Trenches 7

SQL report: Region Source

June 21, 2007 ApEx Lessons from the

Trenches 8

SQL report: Attributes

June 21, 2007 ApEx Lessons from the

Trenches 9

Automated report link

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) || '&nbsp' ||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 17

Checkboxes

PLSQL-generated SQL

Page process

June 21, 2007 ApEx Lessons from the

Trenches 18

Check-all checkbox

From Sergio Leunissen’s Blog

June 21, 2007 ApEx Lessons from the

Trenches 19

Grievance listing

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 25

Upload process

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 28

Download report

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 31

URL with checksum

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 33

Checksum in PLSQL region

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 35

Security through branching

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 41

User activity

or

select * from htmldb_activity_log

June 21, 2007 ApEx Lessons from the

Trenches 42

Integrating apps

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 44

Application Express skill set

June 21, 2007 ApEx Lessons from the

Trenches 45

Thank you!

For more information:Bill [email protected]