Refactoring Application Express Greg Jarmiolowski SQLPrompt LLC 1
Refactoring Application Express Too often the design is determined by the first way everyone agrees it would work Refactoring SQL Applications, Stéphan Faroult 2
Refactoring Application Express What is Refactoring Refactoring Goals and Focus Areas APEX Focus Areas for Refactoring Finding What to Refactor Strategies and Challenges Process Overview Example Refactorings 3
What is Refactoring Stepwise Refinement Not just tuning Not intended to provide new functionality BUT It can lay groundwork for new functionality Evolution = Adapt or Die An effective architecture is one in which the most likely changes are also the easiest to make. Software architecture in practice, Len Bass 4
What is Refactoring in APEX In APEX code is organized within a framework Rewriting code goes hand in hand with reorganizing the application APEX architecture informs choices 5
If it ain t broke Why Immediate Needs Security Performance Simplify maintenance Scalability Data integrity Refactor Future Goals Extend functionality UI Changes AJAX ~80% of effort in systems occurs after deployment 6
Refactoring Goals Simplify Enhance performance Take advantage of new features Enhance security Scalability Reusability Decoupling Specific vs. Generic 7
Coding Practice Goals Reduce Redundant Code Dynamic SQL HTML in SQL and PL/SQL Small Code Units Stored Object Names SPODIFICATION Adopt a Meta Data Mindset 8
Goals and Strategies Goal Strategy Performance Inter-element Communication Modifiability Element Responsibilities Security Inter-Element Communication Scalability Localization of Resources Ability to Subset Inter-Element Usage Reusability Inter-Element Coupling Source: Carnegie Mellon Software Engineering Institute 9
Simplification Look for opportunities to SPODIFY Conditions Application Items Application Computations Application Processes Report SQL 10
Performance Caching Region Cache SQL Cache Hint (11g) Function Result Cache (11g) Statement Tuning 11
Take Advantage of New Features Take advantage of new features in APEX WWV_FLOW_ASSERT APEX_UTIL.JSON_FROM_XX JavaScript APIs (apex_ns_3_1.js) Prepare for new features in Application Data Access Layer API Application Processes 12
Security SQL Injection VPD LDAP Integration Single Sign On 13
Scalability Closely related to performance Localization of Resources Session State Data PPR/Cascading LOVs Use of Static Files one big file vs several smaller ones store static files outside of DB Reduce Network Trips Reduce Individual DB Reads 14
Reusability Decoupling Stored predicates Rules Manager/Expression Filter Queues and Jobs APIs encapsulating tables Web Services Workflow AJAX URI dependence 15
Decoupling - Rules Manager/Expression Filter 16
Specific vs. Generic Generalization Adds flexibility Increases centralization Specificity Can enhance performance Can ease troubleshooting 17
Refactoring APEX How can refactoring be applied to APEX? Examine APEX architecture Look for crossover functionality Look for opportunities to SPODIFY 18
APEX Architecture 19
Refactoring APEX Explore the Architecture Look for crossover functionality Use APEX views and application reports Look for side effects Consider page lifecycle 20
APEX Refactorings Items Page, App, Temp Conditions Processes Auto vs. PL/SQL Validations Branches Computations 21
APEX Refactorings Reports Regions HTP vs. Template JavaScript - AJAX Globalization 22
APEX Refactorings Items Page, App, Temporary Replacing page items with Application Items Replacing page items in AJAX calls with temporary items addglobals() 23
APEX Refactorings Conditions Conditions are everywhere Perfect for centralizing with boolean functions 24
APEX Refactorings Processes Auto vs. PL/SQL Automatic DML and Row Fetch Very flexible Built-in optimistic locking Item to column mapping Lacks logging No control over errors Auto row fetched data not persisted* *http://c2anton.blogspot.com/2008/12/oracle-application-express-apex-three.html 25
APEX Refactorings Validations Ordering and short circuiting Reduce redundancy Not much crossover Extract logic into computation 26
APEX Refactorings Branches Use of ITEM vs Page number App Level Item vs Page Level New set session state option Ordering and short circuiting 27
APEX Refactorings Computations Reduce redundancy with a process Combine calls to the same table Set values in a process 28
APEX Refactorings Reports Replace dynamic SQL source Move HTML to column attributes and templates Simplify SQL with DB view Reusable predicates SQL calculated attributes APEX_COLLECTION 29
APEX Refactorings Regions HTP vs. Template Go beyond HTP.P Htp.anchor Htp.tablexxx APEX_ITEM Updatable Report Translatable text 30
APEX Refactorings JavaScript AJAX $ functions apex.ajax.ondemand AddArrayItems() AddPageItems() APEX_UTIL.JSON_FROM_SQL $d_lov_from_json 31
AJAX URL Decoupling f?p App Page Session Request Debug Clear Cache Item Names Item Values PrinterFriendly wwv_flow.show p_flow_id p_flow_step_id p_instance p_request p_debug p_clear_cache p_arg_names p_arg_values p_printer_friendly $a_report() - APEX PPR pagination and sorting function var l_url = 'p='+$v('pflowid')+':'+$v('pflowste pid')+':'+$v('pinstance')+':flow_p PR_OUTPUT_R'+pId+'_'; var ajax = new htmldb_get(null,null,null,null,null,'f',l _URL); var greturn = ajax.get(); 32
APEX Refactorings Globalization APEX_LANG Text Messages Shared Items -> Globalization 33
Finding What to Refactor Beauty of APEX is the metadata APEX Component Reports APEX Views Object Dependencies Page Referenced View 34
Finding What to Refactor Hack the Object Depenendencies Report APEX_030200.wwv_flow_theme_files.find_obj ect_dependencies (p_flow_id=>:p1_app_id, p_page_id=>null); Need to grant rights to package 35
Finding What to Refactor select SEQ_ID AS ORDER_SEQ, C001 AS schema_name, C002 AS object_name, C003 AS object_type, C004 AS component_name, C005 AS page_number, C006 AS component_id, C007 AS component_source, C008 AS app_id, C009 AS bound_items, C010 AS component_type, C011 AS component_source_type from htmldb_collections where c008 = :P1_APP_ID and c002 <> 'PLITBLM' and collection_name = 'ALL_DEPENDENCIES' 36
Finding What to Refactor 37
Strategies Decide goals Determine scope Choose methods Create plan Test Document Release 38
Strategies Important Considerations System owner needs System owner capabilities Future changes and growth System owner buy in Every design decision comes down to cost, benefit, and risk The Data Model Resource Book - Volume 3, Len Silverston 39
Strategies System Owner Considerations Capabilities and capacity Complexity of resultant architecture Maintenance of resultant system Administration of resultant system New processes, scheduled jobs Exception reporting 40
Strategies Future changes and growth How far do you go in anticipating the progression of needs Does the system require more or less flexibility in design Consider reusing or integrating subsets 41
Strategies Getting Buy In Original developer objections Time vs. Benefit Low Hanging Fruit Don t estimate performance gains Prove inefficiencies 42
Strategies Smaller changes are easier Break your work into smaller tasks Determine scope of changes The greater the coupling the harder the refactoring Track changes carefully 43
Strategies Measuring your work How will you measure progress? What metrics go with your goals? Can you build instrumentation from your analysis tools? 44
Process Overview Determine refactoring(s) needed Choose the method(s) Determine the scope Create a new version with changes Test Document Release 45
Example Refactorings Add a column to the database Add column to db Add item to page Set the db column attributes - Auto Fetch and Auto DML OR Add column to fetch or calculation Add column to DML process 46
Example Refactorings Replace SQL Exists condition with function SQL Conditions might seem innocuous in the beginning but once your data grows you might begin to see a performance hit If this filtered on an un-indexed column or it includes a function call performance can suffer Conditionals are often redundant 47
Example Refactorings Replace condition with authorization scheme If the condition relies on user dependent attributes alone it is a good candidate for an authorization scheme Probably an even better candidate for a stored function An even better candidate for 11g Function Result Cache 48
Example Refactorings Replace page process with on demand application process May entail the creation of app items New app items need to have values set Extends possibilities for using AJAX 49
Example Refactorings Replace multiple branches with process to set target page and branch to it May reduce redundant calls to functions within branch conditions Good way to reduce function and/or query based conditions Puts page branch logic in one block Eliminates the problem of a branch reordering causing unexpected results 50
Example Refactorings Replace Dynamic SQL with Static SQL Variable column lists can be made conditional in the report attributes Variable table lists might indicate a bigger problem with your design 51
Example Refactorings Replace Dynamic SQL with Static SQL Consider the use of CASE for nested conditionals Think beyond this column equals that Case construct allows nested conditions if this is true then check these other things Put null conditions first to take advantage of short-circuit evaluation Order conditions from most to least true 52
Example Refactorings Example using CASE for where conditions SELECT * FROM my_table WHERE 1 = CASE WHEN :G_SEC_LEV < 3 AND :G_FACILITY_ID = 0 THEN CASE WHEN region_id = :G_REGION_ID THEN 1 ELSE 0 END WHEN :G_SEC_LEV < 3 AND :G_FACILITY_ID!= 0 THEN CASE WHEN facility_id = :G_FACILITY_ID THEN 1 ELSE 0 END WHEN :P69_REGION_ID!= 0 THEN CASE WHEN region_id = :G_REGION_ID THEN 1 ELSE 0 END ELSE 1 END 53
Example Refactorings Example using CASE for columns SELECT CASE WHEN INSTR(':' sec_lev ':' THEN, ':' :G_SEC_LEV ':')>0 CASE WHEN next_sec_lev IS NOT NULL THEN '<a href="#" onclick="push(' g.grid '); return false;">push</a>' WHEN next_sec_lev IS NULL THEN '<a href="f?p=&app_id.:71:&app_session.:::71:p71_grid: ' g.grid '">Submit</a>' 54
Example Refactorings CASE statement constructs Given mutually exclusive conditions a-d within 100 records The ordering of the evaluation affects the total number of evaluations CONDITION TRUE FALSE # EVALS a 10 90 100 b 20 80 90 c 30 70 70 d 40 60 40 total records -> 100 300 CONDITION TRUE FALSE # EVALS d 40 60 100 c 30 70 60 b 20 80 30 a 10 90 10 total records -> 100 200 55
Example Refactorings Replace Automated Row Fetch with PL/SQL expression Automated Row Fetch doesn t persist session state No data is not an error Consider using record types FUNCTION get_emp(empid IN NUMBER) RETURN employee%rowtype; DECLARE emp_rec employee%rowtype; BEGIN emp_rec := get_emp(:px_empid); :PX_emp_lname := emp_rec.lname; 56
Example Refactorings Replace Automatic DML with PL/SQL Allows for custom error handling Consider (again) using record types PROCEDURE update_emp(empid IN employee%rowtype); DECLARE emp_rec employee%rowtype; BEGIN emp_rec.emp_id : = :PX_EMPID; emp_rec.lname := :PX_EMP_LNAME; update_emp(emp_rec); 57
Example Refactorings Rewriting Conditions Conditions are everywhere Reduce redundancy Reduce use of session state (items) May need to find PL/SQL equivalents for unique condition types Current Page = Page Submitted 58
Example Refactorings Conditions are everywhere APEX_APPLICATION_BC_ENTRIES APEX_APPLICATION_COMPUTATIONS APEX_APPLICATION_LIST_ENTRIES APEX_APPLICATION_LOV_ENTRIES APEX_APPLICATION_NAV_BAR APEX_APPLICATION_PAGES APEX_APPLICATION_PAGE_BRANCHES APEX_APPLICATION_PAGE_BUTTONS APEX_APPLICATION_PAGE_COMP APEX_APPLICATION_PAGE_IR APEX_APPLICATION_PAGE_IR_COL APEX_APPLICATION_PAGE_IR_COND APEX_APPLICATION_PAGE_ITEMS APEX_APPLICATION_PAGE_PROC APEX_APPLICATION_PAGE_REGIONS APEX_APPLICATION_PAGE_RPT_COLS APEX_APPLICATION_PAGE_VAL APEX_APPLICATION_PARENT_TABS APEX_APPLICATION_PROCESSES APEX_APPLICATION_SHORTCUTS APEX_APPLICATION_TABS WWV_FLOW_LIST_ITEMS WWV_FLOW_MENU_OPTIONS WWV_FLOW_PAGE_PLUGS WWV_FLOW_REGION_REPORT_COLUMN WWV_FLOW_REGION_REPORT_FILTER WWV_FLOW_STEPS (Cache condition) WWV_FLOW_STEP_BRANCHES WWV_FLOW_STEP_BUTTONS WWV_FLOW_STEP_VALIDATIONS WWV_FLOW_TABS WWV_FLOW_TOPLEVEL_TABS 59
Example Refactorings Replacing Conditions with Authorizations Can be evaluated per session or page view Can be subscribed to for sharing across applications Can be reused in Conditions apex_util.public_check_authorization ( AUTHORIZATION_SCHEME_NAME ) Can be reset as needed (all or nothing) apex_util.reset_authorizations 60
Example Refactorings Replacing Conditions with Authorizations Available for the following components Application Computation Navigation Bar List Items Breadcrumb Entry Region Process (page and app level) Report Column Page Branch Button Item Validation Tab 61
Example Refactorings Replacing Item Level LOV with shared LOV WWV_FLOW_STEP_ITEMS.LOV Shows LOVs defined at item level 62
Suggested Reading Refactoring Databases: Evolutionary Database Design Scott W. Ambler and Pramodkumar J. Sadalage 63
Suggested Reading Refactoring SQL Applications Stephane Faroult and Pascal L'Hermite 64
Suggested Reading Oracle PL/SQL Best Practices Steven Feuerstein 65
Refactoring Application Express Greg Jarmiolowski SQLPrompt LLC 66