Presentation is loading. Please wait.

Presentation is loading. Please wait.

Professional Software Development using APEX

Similar presentations


Presentation on theme: "Professional Software Development using APEX"— Presentation transcript:

1 Professional Software Development using APEX
Rob van Wijk

2 About me Rob van Wijk since 1972 Oracle since 1995 Ciber since 2003
Oracle ACE since 2008 Oracle University SQL Masterclass since 2011 Forums: OTN & Stack Overflow Blog: rwijk.blogspot.com

3 My APEX experience Starting with HTMLDB/APEX since 2005
Own APEX website since 2009 Programming OGh APEX day conference since 2010 Ciber APEXSoFa since early 2012 Working with APEX since November 2012

4 Development Test User Acceptance

5 pro·fes·sion·al [pruh-fesh-uh-nl]
adjective 3. appropriate to a profession: professional objectivity. Source:

6 The Joel Test Do you use source control?
Can you make a build in one step? Do you use source control? Do you make daily builds? Do you have a bug database? Do you fix bugs before writing new code? Do you have an up-to-date schedule? Do you have a spec? Do programmers have quiet working conditions? Do you use the best tools money can buy? Do you have testers? Do new candidates write code during their interview? Do you do hallway usability testing? Source:

7 The Joel Test Do you use source control?
Can you make a build in one step? Do you use source control? Do you make daily builds? Do you have a bug database? Do you fix bugs before writing new code? Do you have an up-to-date schedule? Do you have a spec? Do programmers have quiet working conditions? Do you use the best tools money can buy? Do you have testers? Do new candidates write code during their interview? Do you do hallway usability testing? Source:

8 Agenda 1. Version Control 2. Parallel Development 3. One-Step Build 4. Daily Build 5. Unit Testing

9 1. Version Control

10 Goal The entire application can be installed completely from files under version control

11

12 svn repository svn commit svn checkout svn update tekst

13 Subversion client for Windows:

14 Subversion client for Mac:
Cornerstone

15 Oracle Application Express APEX_040100 schema
UI schema, APEX’s parsing schema views and packages containing minimal set of API layer calls API calls API schema Database packages with business logic views selecting from tables select, insert, update & delete DATA schema Tables, Data, Indexes, Sequences

16 UI, API & DATA schema Minimal system privileges
No CREATE SESSION privilege Password generated with dbms_random.string(‘a’,30)

17

18 APEXExport APEXExportSplitter

19

20 META schema SQL> select * from meta.mta_applications 2 /CODE NAME APEX_APPLICATION_ID CV Ciber CV's SCA Standen Collectie Applicatie rows selected.

21 META schema SQL> desc meta.mta_admin...PROCEDURE ADD_APPLICATION Argument Name Type In/Out Default? P_CODE VARCHAR2(10) IN P_NAME VARCHAR2(50) IN P_APEX_APPLICATION_ID NUMBER(5) IN ... FUNCTION APEX_APPLICATION_ID RETURNS NUMBER Argument Name Type In/Out Default? P_APP_CODE VARCHAR2(10) IN...PROCEDURE REMOVE_APPLICATION Argument Name Type In/Out Default? P_CODE VARCHAR2(10) IN...

22 A challenge with APEX and file based version control

23 Your APEX workspace application
Your APEX working copy Your APEX workspace application

24 get the delta from your APEX workspace into your working copy
svn update put your colleagues’ changes plus your delta back into your APEX workspace

25 z rm -rf $HOME/ciber/apexsofa/$1/apexcd $HOME/ciber/apexsofa/$1java oracle.apex.APEXExport\ -db ourserver:1521:APEXSOFAO\ -user apex_040100\ -password secret\ -applicationid $2\ -skipExportDatejava oracle.apex.APEXExportSplitter f$2.sqlmv f$2 apexcd apexsed <install.sql\ >../non- apex/install/install_apex_components.sqlsvn status | grep ^\? | awk '{print $2}' | xargs svn addsvn status | grep ^\! | awk '{print $2}' | xargs svn delete --forcesvn updatecd ... non- apex/install/reinstall_apex z

26 Merge conflict MacBookPro:application robvanwijk$ svn update
Conflict discovered in 'pages/page_00004.sql'. Select: (p) postpone, (df) diff-full, (e) edit, (mc) mine-conflict, (tc) theirs-conflict, (s) show all options: p C pages/page_00004.sql Updated to revision 96. Summary of conflicts: Text conflicts: 1 MacBookPro:application robvanwijk$ ls page_00004.sql* page_00004.sql page_00004.sql.mine page_00004.sql.r95 page_00004.sql.r96

27 Merge conflict wwv_flow_api.create_page_button(
p_id => wwv_flow_api.g_id_offset, p_flow_id => wwv_flow.g_flow_id, p_flow_step_id => 4, p_button_sequence=> 10, p_button_plug_id => wwv_flow_api.g_id_offset, p_button_name => 'CREATE', p_button_action => 'REDIRECT_PAGE', p_button_image => 'template:'||to_char( wwv_flow_api.g_id_offset), p_button_is_hot=>'N', <<<<<<< .mine p_button_image_alt=> 'Maak aan', ======= p_button_image_alt=> 'Aanmaken', >>>>>>> .r96 p_button_position=> 'REGION_TEMPLATE_CREATE', p_button_alignment=> 'RIGHT', p_button_redirect_url=> 'f?p=&APP_ID.:5:&SESSION.::&DEBUG.:5', p_required_patch => null + wwv_flow_api.g_id_offset);

28 whenever sqlerror exit failure

29 Development database APEX Schema META Workspace Ciber CV SCA
User INSTALL Schema CV_UI Schema SCA_UI Schema CV_API Schema SCA_API Schema CV_DATA Schema SCA_DATA

30 2. Parallel Development

31 “The developer should be free to experiment as much as possible, safe in the knowledge that the worst that could happen is they destroy only their own environment and not impact the productivity of others.” - Nick Ashley Source:

32 each developer has its own four database schemas, for instance: RWIJK
RWIJK_UI RWIJK_API RWIJK_DATA

33 and each developer has its own
APEX workspace

34 Development database APEX Schema META Workspace Ciber CV SCA
Workspace RWIJK SCA Workspace MPLAS CV SCA User INSTALL Schema CV_UI Schema SCA_UI Schema RWIJK_UI Schema MPLAS_UI User RWIJK Schema CV_API Schema SCA_API Schema RWIJK_API Schema MPLAS_API User MPLAS Schema CV_DATA Schema SCA_DATA Schema RWIJK_DATA Schema MPLAS_DATA

35 META schema SQL> select code , name , apex_application_id_from , apex_application_id_until from meta.mta_developers 6 /CODE NAME APEX_APPLICATION_ID_FROM APEX_APPLICATION_ID_UNTIL RWIJK Rob van Wijk MPLAS Marcel van der Plas MHOEFS Marcel Hoefs EASLAN Erdal Aslan ASUVEREIN Arne Suverein EHAMERS Etienne Hamers LSAVALKA Larysa Savalka rows selected.

36 META schema SQL> desc meta.mta_admin...PROCEDURE ADD_DEVELOPER Argument Name Type In/Out Default? P_CODE VARCHAR2(10) IN P_NAME VARCHAR2(30) IN P_APEX_APPLICATION_ID_FROM NUMBER(5) IN P_APEX_APPLICATION_ID_UNTIL NUMBER(5) IN ... PROCEDURE REMOVE_DEVELOPER Argument Name Type In/Out Default? P_CODE VARCHAR2(10) IN...

37 META schema SQL> select dev_code , app_code , apex_application_id from meta.mta_application_copies order by apex_application_id 6 /DEV_CODE APP_CODE APEX_APPLICATION_ID RWIJK CV RWIJK SCA MPLAS CV MPLAS SCA MHOEFS SCA MHOEFS CV EASLAN SCA EASLAN CV ASUVEREIN SCA EHAMERS SCA LSAVALKA SCA LSAVALKA CV rows selected.

38 META schema SQL> desc meta.mta_admin
...PROCEDURE ADD_APPLICATION_COPY Argument Name Type In/Out Default? P_DEV_CODE VARCHAR2(10) IN P_APP_CODE VARCHAR2(10) IN P_APEX_APPLICATION_ID NUMBER(5) IN DEFAULT FUNCTION APEX_APPLICATION_ID RETURNS NUMBER Argument Name Type In/Out Default? P_APP_CODE VARCHAR2(10) IN P_SCHEMAPREFIX VARCHAR INFUNCTION APEX_WORKSPACE_ID RETURNS NUMBER Argument Name Type In/Out Default? P_SCHEMAPREFIX VARCHAR INPROCEDURE REMOVE_APPLICATION_COPY Argument Name Type In/Out Default? P_DEV_CODE VARCHAR2(10) IN P_APP_CODE VARCHAR2(10) IN ...

39 set define off set verify off set feedback off WHENEVER SQLERROR EXIT SQL.SQLCODE ROLLBACK begin wwv_flow.g_import_in_progress := true; end; / --application/set_environment prompt APPLICATION SCA -- -- Application Export: -- Application: -- Name: SCA -- Exported By: -- Flashback: -- Export Type: Application Export -- Version: -- Instance ID: -- Import: -- Using application builder -- or -- Using SQL*Plus as the Oracle user APEX_ or as the owner (parsing schema) of the application. -- Application Statistics: -- Pages: Items: Computations: Validations: Processes: Regions: Buttons: Dynamic Actions: -- Shared Components Breadcrumbs: Entries Items: Processes: Parent Tabs: Tab Sets: Tabs: NavBars: Lists: Shortcuts: Themes: Templates: Page: List: Report: Label: Region: Messages: Build Options: AAAA PPPPP EEEEEE XX XX AA AA PP PP EE XX XX AA AA PP PP EE XX XX -- AAAAAAAAAA PPPPP EEEE XXXX -- AA AA PP EE XX XX -- AA AA PP EE XX XX -- AA AA PP EEEEEE XX XX prompt Set Credentials... begin -- Assumes you are running the script connected to SQL*Plus as the Oracle user APEX_ or as the owner (parsing schema) of the application. wwv_flow_api.set_security_group_id(p_security_group_id=>nvl(wwv_flow_application_install.get_workspace_id, )); end; select value into wwv_flow_api.g_nls_numeric_chars from nls_session_parameters where parameter='NLS_NUMERIC_CHARACTERS'; begin execute immediate 'alter session set nls_numeric_characters=''.,'''; begin wwv_flow.g_browser_language := 'en'; end; prompt Check Compatibility... -- This date identifies the minimum version required to import this file. wwv_flow_api.set_version(p_version_yyyy_mm_dd=>' '); prompt Set Application ID... -- SET APPLICATION ID wwv_flow.g_flow_id := nvl(wwv_flow_application_install.get_application_id,10001); wwv_flow_api.g_id_offset := nvl(wwv_flow_application_install.get_offset,0); null; --application/delete_application -- Remove Application wwv_flow_api.remove_flow(nvl(wwv_flow_application_install.get_application_id,10001)); wwv_flow_audit.remove_audit_trail(nvl(wwv_flow_application_install.get_application_id,10001)); --application/create_application wwv_flow_api.create_flow( p_id => nvl(wwv_flow_application_install.get_application_id,10001), p_display_id=> nvl(wwv_flow_application_install.get_application_id,10001), p_owner => nvl(wwv_flow_application_install.get_schema,'RWIJK_UI'), p_name => nvl(wwv_flow_application_install.get_application_name,'SCA'), p_alias => nvl(wwv_flow_application_install.get_application_alias,'F10001'), p_page_view_logging => 'YES', p_default_page_template=> wwv_flow_api.g_id_offset, p_printer_friendly_template=> wwv_flow_api.g_id_offset, p_default_region_template=> wwv_flow_api.g_id_offset, p_error_template=> wwv_flow_api.g_id_offset, p_page_protection_enabled_y_n=> 'Y', p_checksum_salt_last_reset => ' ', p_max_session_length_sec=> null, p_compatibility_mode=> '4.1', p_home_link=> 'f?p=&APP_ID.:1:&SESSION.', p_flow_language=> 'nl', p_flow_language_derived_from=> 'FLOW_PRIMARY_LANGUAGE', p_allow_feedback_yn=> 'N', p_date_format=> 'dd-mm-yyyy', p_date_time_format=> 'dd-mm-yyyy hh24:mi:ss', p_timestamp_format=> 'dd-mm-yyyy hh24:mi:ssxff', p_timestamp_tz_format=> 'dd-mm-yyyy hh24:mi:ssxff tzr', p_flow_image_prefix => nvl(wwv_flow_application_install.get_image_prefix,'/i/'), p_publish_yn=> 'N', p_documentation_banner=> '', p_authentication=> 'PLUGIN', p_authentication_id=> wwv_flow_api.g_id_offset, p_login_url=> '', p_logout_url=> '', p_application_tab_set=> 0, p_public_url_prefix => '', p_public_user=> '', p_dbauth_url_prefix => '', p_proxy_server=> nvl(wwv_flow_application_install.get_proxy,''), p_cust_authentication_process=> '', p_cust_authentication_page=> '', p_custom_auth_login_url=> '', p_flow_version=> 'release 1.0', p_flow_status=> 'AVAILABLE_W_EDIT_LINK', p_flow_unavailable_text=> '', p_build_status=> 'RUN_AND_BUILD', p_exact_substitutions_only=> 'Y', p_browser_cache=>'N', p_browser_frame=>'D', p_vpd=> '', p_vpd_teardown_code=> '', p_csv_encoding=> 'Y', p_default_error_display_loc=> 'INLINE_WITH_FIELD_AND_NOTIFICATION', p_theme_id => 24, p_default_label_template => wwv_flow_api.g_id_offset, p_default_report_template => wwv_flow_api.g_id_offset, p_default_list_template => wwv_flow_api.g_id_offset, p_default_menu_template => wwv_flow_api.g_id_offset, p_default_button_template => wwv_flow_api.g_id_offset, p_default_chart_template => wwv_flow_api.g_id_offset, p_default_form_template => wwv_flow_api.g_id_offset, p_default_wizard_template => wwv_flow_api.g_id_offset, p_default_tabform_template => wwv_flow_api.g_id_offset, p_default_reportr_template => wwv_flow_api.g_id_offset, p_default_menur_template => wwv_flow_api.g_id_offset, p_default_listr_template => wwv_flow_api.g_id_offset, p_default_irr_template => wwv_flow_api.g_id_offset, p_last_updated_by => 'RWIJK', p_last_upd_yyyymmddhh24miss=> ' ', p_required_roles=> wwv_flow_utilities.string_to_table2('')); prompt ...authorization schemes --application/shared_components/navigation/navigation_bar prompt ...navigation bar entries wwv_flow_api.create_icon_bar_item( p_id => wwv_flow_api.g_id_offset, p_flow_id => wwv_flow.g_flow_id, p_icon_sequence=> 200, p_icon_image => '', p_icon_subtext=> 'Logout', p_icon_target=> '&LOGOUT_URL.', p_icon_image_alt=> 'Logout', p_icon_height=> 32, p_icon_width=> 32, p_icon_height2=> 24, p_icon_width2=> 24, p_nav_entry_is_feedback_yn => 'N', p_icon_bar_disp_cond=> '', p_icon_bar_disp_cond_type=> '', p_begins_on_new_line=> '', p_cell_colspan => 1, p_onclick=> '', p_icon_bar_comment=> ''); prompt ...application processes prompt ...application items prompt ...application level computations prompt ...Application Tabs prompt ...Application Parent Tabs prompt ...Shared Lists of values prompt ...Application Trees --application/pages/page_groups prompt ...page groups --application/pages/page_00001 prompt ...PAGE 1: Page 1 wwv_flow_api.create_page ( p_flow_id => wwv_flow.g_flow_id ,p_id => 1 ,p_name => 'Page 1' ,p_step_title => 'Page 1' ,p_step_sub_title => 'Page 1' ,p_step_sub_title_type => 'TEXT_WITH_SUBSTITUTIONS' ,p_include_apex_css_js_yn => 'Y' ,p_cache_page_yn => 'N' ,p_help_text => 'No help is available for this page.' ,p_last_upd_yyyymmddhh24miss => ' ' ); declare s varchar2(32767) := null; l_clob clob; l_length number := 1; s := null; wwv_flow_api.create_page_plug ( p_id=> wwv_flow_api.g_id_offset, p_flow_id=> wwv_flow.g_flow_id, p_page_id=> 1, p_plug_name=> 'Breadcrumbs', p_region_name=>'', p_escape_on_http_output=>'N', p_plug_template=> wwv_flow_api.g_id_offset, p_plug_display_sequence=> 1, p_plug_display_column=> 1, p_plug_display_point=> 'REGION_POSITION_01', p_plug_source=> s, p_plug_source_type=> 'M'|| to_char( wwv_flow_api.g_id_offset), p_menu_template_id=> wwv_flow_api.g_id_offset, p_plug_query_row_template=> 1, p_plug_query_headings_type=> 'COLON_DELMITED_LIST', p_plug_query_row_count_max => 500, p_plug_display_condition_type => '', p_plug_caching=> 'NOT_CACHED', p_plug_comment=> ''); -- ...updatable report columns for page 1 --application/pages/page_00101 prompt ...PAGE 101: Login ,p_id => 101 ,p_name => 'Login' ,p_alias => 'LOGIN' ,p_step_title => 'Login' ,p_first_item => 'AUTO_FIRST_ITEM' ,p_autocomplete_on_off => 'OFF' ,p_step_template => wwv_flow_api.g_id_offset ,p_page_is_public_y_n => 'Y' p_id=> wwv_flow_api.g_id_offset, p_page_id=> 101, p_plug_name=> 'Login', p_plug_template=> wwv_flow_api.g_id_offset, p_plug_display_sequence=> 10, p_plug_display_point=> 'AFTER_SHOW_ITEMS', p_plug_source_type=> 'STATIC_TEXT', h varchar2(32767) := null; wwv_flow_api.create_page_item( p_id=> wwv_flow_api.g_id_offset, p_flow_step_id=> 101, p_name=>'P101_USERNAME', p_data_type=> '', p_is_required=> false, p_accept_processing=> 'REPLACE_EXISTING', p_item_sequence=> 10, p_item_plug_id => wwv_flow_api.g_id_offset, p_use_cache_before_default=> '', p_prompt=>'Username', p_display_as=> 'NATIVE_TEXT_FIELD', p_lov_display_null=> 'NO', p_lov_translated=> 'N', p_cSize=> 40, p_cMaxlength=> 100, p_cHeight=> null, p_begin_on_new_line=> 'YES', p_begin_on_new_field=> 'YES', p_colspan=> 2, p_rowspan=> 1, p_label_alignment=> 'RIGHT', p_field_alignment=> 'LEFT', p_field_template=> wwv_flow_api.g_id_offset, p_is_persistent=> 'Y', p_attribute_01 => 'N', p_attribute_02 => 'N', p_attribute_03 => 'N', p_item_comment => ''); p_id=> wwv_flow_api.g_id_offset, p_name=>'P101_PASSWORD', p_item_sequence=> 20, p_prompt=>'Password', p_display_as=> 'NATIVE_PASSWORD', p_colspan=> 1, p_attribute_01 => 'Y', p_attribute_02 => 'Y', p_id=> wwv_flow_api.g_id_offset, p_name=>'P101_LOGIN', p_item_sequence=> 30, p_item_default=> 'Login', p_prompt=>'Login', p_source=>'LOGIN', p_source_type=> 'STATIC', p_display_as=> 'BUTTON', p_cSize=> null, p_cMaxlength=> null, p_tag_attributes => 'template:'||to_char( wwv_flow_api.g_id_offset), p_begin_on_new_line=> 'NO', p_label_alignment=> 'LEFT', p_button_action => 'SUBMIT', p_button_is_hot=>'N', p varchar2(32767) := null; p:=p||'apex_authentication.send_login_username_cookie ('||unistr('\000a')|| ' p_username => lower(:P101_USERNAME) );'; wwv_flow_api.create_page_process( p_id => wwv_flow_api.g_id_offset, p_flow_step_id => 101, p_process_sequence=> 10, p_process_point=> 'AFTER_SUBMIT', p_process_type=> 'PLSQL', p_process_name=> 'Set Username Cookie', p_process_sql_clob => p, p_process_error_message=> '', p_error_display_location=> 'INLINE_IN_NOTIFICATION', p_process_success_message=> '', p_process_is_stateful_y_n=>'N', p_process_comment=>''); p:=p||'apex_authentication.login('||unistr('\000a')|| ' p_username => :P101_USERNAME,'||unistr('\000a')|| ' p_password => :P101_PASSWORD );'; p_id => wwv_flow_api.g_id_offset, p_process_sequence=> 20, p_process_name=> 'Login', p:=p||'101'; p_id => wwv_flow_api.g_id_offset, p_process_sequence=> 30, p_process_type=> 'CLEAR_CACHE_FOR_PAGES', p_process_name=> 'Clear Page(s) Cache', p:=p||':P101_USERNAME := apex_authentication.get_login_username_cookie;'; p_id => wwv_flow_api.g_id_offset, p_process_point=> 'BEFORE_HEADER', p_process_name=> 'Get Username Cookie', p_error_display_location=> 'ON_ERROR_PAGE',

40 ( to_char(wwv_seq.nextval) ||
select to_number ( to_char(wwv_seq.nextval) || lpad( substr( abs(wwv_flow_random.rand), 1, 5 ),5, '0' ) || ltrim(to_char(mod(abs(hsecs), ),'000000')) ) into g_curr_val from sys.v_$timer; Source::

41 add offset number when importing
apex_application_install.generate_offset apex_application_install.set_offset

42 subtract offset number when exporting
sed -E 's/([0-9]+)([ ]*\+[ ]*wwv_flow_api.g_id_offset)/^\1^\2/' <f$2.sql | awk -F^ '{if(length($3)>0) {print $1 $2-ENVIRON["offset"] $3} else {print $0}}' >f$2.sql

43 META schema SQL> select code , name , apex_application_id_from id_from , apex_application_id_until id_until , apex_id_offset from meta.mta_developers 7 /CODE NAME ID_FROM ID_UNTIL APEX_ID_OFFSET RWIJK Rob van Wijk MPLAS Marcel van der Plas MHOEFS Marcel Hoefs EASLAN Erdal Aslan ASUVEREIN Arne Suverein EHAMERS Etienne Hamers LSAVALKA Larysa Savalka rows selected.

44 META schema SQL> desc meta.mta_admin
...FUNCTION APEX_ID_OFFSET RETURNS NUMBER(20) Argument Name Type In/Out Default? P_SCHEMAPREFIX VARCHAR IN ...

45 3. One-Step Build

46 Reduce the chance for errors during installation
Goal Reduce the chance for errors during installation

47 install.sql uninstall.sql install_apex.sql uninstall_apex.sql install_db.sql uninstall_db.sql reinstall.sql reinstall_apex.sql reinstall_db.sql

48 remark remark install_db.sql remark Marcel Hoefs 06 juni 2012 column current_schema new_value curschema select sys_context('userenv','current_schema') current_schema from dual / define SCHEMAPREFIX='&1' define APPLICATIE='sca' prompt *************************************************************************** prompt Installeer db-gedeelte van &APPLICATIE in schema's &SCHEMAPREFIX._data, &SCHEMAPREFIX._api en &SCHEMAPREFIX._ui define tables_path='&APPLICATIE./non-apex/data/tables/' define sequences_path='&APPLICATIE./non-apex/data/sequences/' define indexes_path='&APPLICATIE./non-apex/data/indexes/' define data_path='&APPLICATIE./non-apex/data/data/' define privs_path='&APPLICATIE./non-apex/data/privileges/' define triggers_path='&APPLICATIE./non-apex/data/triggers/' define packages_path='&APPLICATIE./non-apex/api/packages/' define package_bodies_path='&APPLICATIE./non-apex/api/package_bodies/' define api_synonyms_path='&APPLICATIE./non-apex/api/synonyms/' define view_path='&APPLICATIE./non-apex/ui/views/' define ui_synonyms_path='&APPLICATIE./non-apex/ui/synonyms/' set verify off alter session set current_schema = &SCHEMAPREFIX._data &SCHEMAPREFIX alter session set current_schema = &SCHEMAPREFIX._api remark Deze applicatie heeft geen API-laag. alter session set current_schema = &SCHEMAPREFIX._ui &SCHEMAPREFIX &SCHEMAPREFIX &SCHEMAPREFIX &SCHEMAPREFIX &SCHEMAPREFIX &SCHEMAPREFIX &SCHEMAPREFIX &SCHEMAPREFIX alter session set current_schema = &CURSCHEMA set verify on undefine SCHEMAPREFIX undefine APPLICATIE undefine CURSCHEMA

49 remark remark uninstall_db.sql remark Marcel Hoefs 6 juni 2012 column current_schema new_value CURSCHEMA select sys_context('userenv','current_schema') current_schema from dual / set verify off define SCHEMAPREFIX='&1' prompt ************************************************************************************* prompt De-installeer db-gedeelte van SCA uit schema's &SCHEMAPREFIX._data, &SCHEMAPREFIX._api en &SCHEMAPREFIX._ui alter session set current_schema = &SCHEMAPREFIX._data remark Verwijder hier alle objecten uit de DATA-laag drop table sca_klanten cascade constraints purge drop table sca_meetinstallaties cascade constraints purge drop table sca_meterstanden cascade constraints purge drop table sca_opnames cascade constraints purge drop sequence sca_klt_seq1 drop sequence sca_mie_seq1 drop sequence sca_msd_seq1 drop sequence sca_one_seq1 alter session set current_schema = &SCHEMAPREFIX._api remark Verwijder hier alle objecten uit de API-laag alter session set current_schema = &SCHEMAPREFIX._ui remark Verwijder hier alle objecten uit de UI-laag drop synonym sca_klanten drop synonym sca_meetinstallaties drop synonym sca_meterstanden drop synonym sca_opnames drop synonym sca_klt_seq1 drop synonym sca_mie_seq1 drop synonym sca_msd_seq1 drop synonym sca_one_seq1 alter session set current_schema = &CURSCHEMA set verify on undefine SCHEMAPREFIX undefine CURSCHEMA

50 remark remark install_apex.sql remark Rob van Wijk, 6 juni 2012 define SCHEMAPREFIX='&1' define APPLICATIE='sca' prompt *************************************************************************** prompt Installeer APEX-gedeelte van &APPLICATIE in de werkruimte horend bij schemaprefix &SCHEMAPREFIX. set verify off column current_schema new_value curschema select sys_context('userenv','current_schema') current_schema from dual / alter session set current_schema = &SCHEMAPREFIX._ui declare cn_schemaprefix constant varchar2(25) := '&SCHEMAPREFIX'; cn_applicatie constant varchar2(30) := '&APPLICATIE'; begin apex_application_install.set_workspace_id(meta.mta_admin.apex_werkruimte_id(cn_schemaprefix)); apex_application_install.set_application_id(meta.mta_admin.apex_applicatie_id(cn_applicatie,cn_schemaprefix)); apex_application_install.set_offset(meta.mta_admin.apex_offset_id(cn_schemaprefix)); apex_application_install.set_schema(upper(cn_schemaprefix) || '_UI'); apex_application_install.set_application_alias ( case lower(cn_schemaprefix) when lower(cn_applicatie) then cn_applicatie else cn_applicatie || '_' || cn_schemaprefix end ); end; whenever sqlerror continue alter session set current_schema = &CURSCHEMA undefine APPLICATIE undefine SCHEMAPREFIX

51 remark remark uninstall_apex.sql remark Rob van Wijk, 6 juni 2012 define SCHEMAPREFIX='&1' define APPLICATIE='sca' prompt *************************************************************************** prompt De-installeer APEX-gedeelte van &APPLICATIE uit werkruimte horend bij schemaprefix &SCHEMAPREFIX. set verify off column current_schema new_value curschema select sys_context('userenv','current_schema') current_schema from dual / alter session set current_schema = &SCHEMAPREFIX._UI remark Dit script wordt gebruikt om zowel het applicatieschema als een gebruikersschema te verwijderen. remark Gebruik package APEX_APPLICATION_INSTALL om precies aan te geven welke applicatie we gaan verwijderen. declare cn_schemaprefix constant varchar2(25) := '&SCHEMAPREFIX'; cn_applicatie constant varchar2(10) := '&APPLICATIE'; begin apex_application_install.set_workspace_id(meta.mta_admin.apex_werkruimte_id(cn_schemaprefix)); apex_application_install.set_application_id(meta.mta_admin.apex_applicatie_id(cn_applicatie,cn_schemaprefix)); end; remark Gebruik de bestaande scripts uit de APEX Export Splitter om de applicatie uit APEX te verwijderen @sca/apex/application/init.sql @sca/apex/application/set_environment.sql @sca/apex/application/delete_application.sql @sca/apex/application/end_environment.sql whenever sqlerror continue remark Zet het huidige schema terug naar de oorspronkelijke waarde alter session set current_schema = &CURSCHEMA set verify on undefine schemaprefix undefine applicatie

52 4. Daily Build

53 to ensure no breakage of the build goes unnoticed
Goal to ensure no breakage of the build goes unnoticed

54 “Extensible continuous integration server”

55 svn repository reinstall.sql svn update reinstall_apex.sql
Application schemas svn repository RWIJK development schemas reinstall.sql svn update reinstall_apex.sql reinstall_db.sql MPLAS development schemas reinstall_apex.sql reinstall_db.sql . . . reinstall_apex.sql reinstall_db.sql LSAVALKA development schemas

56

57

58 Started by timer Updating revision: Nov 25, :01:15 AM depth:infinity ignoreExternals: false At revision 95 no change for since the previous build [workspace] $ /bin/sh -xe /tmp/hudson sh + ORAENV_ASK=NO + ORACLE_SID=APEXSOFAO + . oraenv ++ SILENT= ++ case ${ORACLE_TRACE:-""} in ++ N= ++ C= ++ echo '\c' ++ grep c ++ N=-n ++ '[' 0 = 0 ']' ++ OLDHOME=/usr/kerberos/bin:/opt/sw/java/jdk1.6.0_30/bin:/usr/local/bin:/bin:/usr/bin:/opt/sw/firefox:/home/gladmin/bin ++ case ${ORAENV_ASK:-""} in ++ NEWSID=APEXSOFAO ++ export ORACLE_SID +++ dbhome APEXSOFAO ++ ORAHOME=/opt/sw/oradmin/product/ /dbhome_1 ++ case $? in ++ ORACLE_HOME=/opt/sw/oradmin/product/ /dbhome_1 ++ export ORACLE_HOME ++ case ${LD_LIBRARY_PATH:-""} in ++ LD_LIBRARY_PATH=/opt/sw/oradmin/product/ /dbhome_1/lib:/opt/sw/java/jdk1.6.0_30/jre/lib/amd64/server:/opt/sw/java/jdk1.6.0_30/jre/lib/amd64:/opt/sw/java/jdk1.6.0_30/jre/../lib/amd64 ++ export LD_LIBRARY_PATH ++ case "$OLDHOME" in ++ case "$PATH" in ++ PATH=/usr/kerberos/bin:/opt/sw/java/jdk1.6.0_30/bin:/usr/local/bin:/bin:/usr/bin:/opt/sw/firefox:/home/gladmin/bin:/opt/sw/oradmin/product/ /dbhome_1/bin ++ export PATH +++ LANG=C +++ ulimit ++ ULIMIT=unlimited ++ '[' 0 = 0 -a unlimited '!=' unlimited ']' ++ ORABASE_EXEC=/opt/sw/oradmin/product/ /dbhome_1/bin/orabase ++ '[' x '!=' x ']' ++ OLD_ORACLE_BASE= ++ '[' -w /opt/sw/oradmin/product/ /dbhome_1/inventory/ContentsXML/oraclehomeproperties.xml ']' ++ '[' '' '!=' true ']' ++ echo 'ORACLE_BASE environment variable is not being set since this' ORACLE_BASE environment variable is not being set since this ++ echo 'information is not available for the current user ID gladmin.' information is not available for the current user ID gladmin. ++ echo 'You can set ORACLE_BASE manually if it is required.' You can set ORACLE_BASE manually if it is required. + unset ORAENV_ASK + cd /opt/sw/hudson/jobs/hudson_sca/workspace + pwd /opt/sw/hudson/jobs/hudson_sca/workspace + sqlplus sca SQL*Plus: Release Production on Sun Nov 25 02:01: Copyright (c) 1982, 2011, Oracle. All rights reserved. Connected to: Oracle Database 11g Enterprise Edition Release bit Production With the Partitioning, OLAP, Data Mining and Real Application Testing options BESTANDSNAAM build_sca_ sql @sca/non-apex/install/reinstall sca @sca/non-apex/install/reinstall_db RWIJK @sca/non-apex/install/reinstall_apex RWIJK @sca/non-apex/install/reinstall_db MHOEFS @sca/non-apex/install/reinstall_apex MHOEFS @sca/non-apex/install/reinstall_db EASLAN @sca/non-apex/install/reinstall_apex EASLAN @sca/non-apex/install/reinstall_db ASUVEREIN @sca/non-apex/install/reinstall_apex ASUVEREIN @sca/non-apex/install/reinstall_db EHAMERS @sca/non-apex/install/reinstall_db LSAVALKA @sca/non-apex/install/reinstall_apex LSAVALKA *************************************************************************** De-installeer APEX-gedeelte van sca uit werkruimte horend bij schemaprefix sca CURRENT_SCHEMA INSTALL APPLICATION SCA Set Credentials... Check Compatibility... API Last Extended: Your Current Version: This import is compatible with version: COMPATIBLE (You should be able to run this import without issues.) Set Application ID... ...done old 1: alter session set current_schema = &CURSCHEMA new 1: alter session set current_schema = INSTALL Session altered. 1 row selected. ************************************************************************************* De-installeer db-gedeelte van SCA uit schema's sca_data, sca_api en sca_ui Table dropped. Sequence dropped. Synonym dropped. Installeer db-gedeelte van sca in schema's sca_data, sca_api en sca_ui Table created. Index created. Table altered. Sequence created. Grant succeeded. Synonym created. Installeer APEX-gedeelte van sca in de werkruimte horend bij schemaprefix sca PL/SQL procedure successfully completed. ...authorization schemes ...navigation bar entries ...application processes ...application items ...application level computations ...Application Tabs ...Application Parent Tabs ...Shared Lists of values ...Application Trees ...page groups ...PAGE 1: Page 1 ...PAGE 4: Klanten beheer ...PAGE 5: Meetinstallaties ...PAGE 8: meetinstallaties bewerken ...PAGE 12: klantlogin ...PAGE 13: Registratienummers ...PAGE 14: meterstanden ...PAGE 15: Meterstanden registreren ...PAGE 101: Login ...lists ...breadcrumbs ...page templates for application: 12000 ......Page template ......Page template ......Page template ......Page template ......Page template ......Page template ......Page template ......Page template ......Page template ......Page template ......Page template ......Page template ......Page template ......Page template ......Page template ......Page template ......Page template ...button templates ......Button Template ......Button Template ......Button Template ......Button Template ......Button Template ......Button Template ......Button Template ...region templates ......region template ......region template ......region template ......region template ......region template ......region template ......region template ......region template ......region template ......region template ......region template ......region template ......region template ......region template ......region template ......region template ......region template ......region template ......region template ......region template ......region template ......region template ......region template ......region template ......region template ......region template ......region template ......region template ......region template ......region template ......region template ......region template ......region template ......region template ...List Templates ......list template ......list template ......list template ......list template ......list template ......list template ......list template ......list template ......list template ......list template ......list template ......list template ......list template ......list template ......list template ......list template ......list template ...report templates ......report template ......report template ......report template ......report template ......report template ......report template ......report template ......report template ......report template ......report template ......report template ...label templates ......label template ......label template ......label template ......label template ......label template ......label template ...breadcrumb templates ......template ......template ...popup list of values templates ......template ...calendar templates ......template ......template ......template ...application themes ......theme ...build options used by application 12000 ...Language Maps for Application 12000 ...messages used by application: 12000 ...dynamic translations used by application: 12000 ...Shortcuts ...web services (9iR2 or better) ...shared queries ...report layouts ...authentication schemes ......authentication ...plugins ...load tables

59 In Hudson build, developers have option to get a fresh development environment each night

60 META schema SQL> select dev_code , app_code , apex_application_id , ind_daily_db_refresh , ind_daily_apex_refresh from meta.mta_application_copies 7 /DEV_CODE APP_CODE APEX_APPLICATION_ID I I RWIJK CV J NRWIJK SCA J JMPLAS CV J NMPLAS SCA N NMHOEFS CV J JMHOEFS SCA J JEASLAN SCA J JEASLAN CV J JASUVEREIN SCA J JEHAMERS SCA J NLSAVALKA SCA J J LSAVALKA CV J J

61 META schema SQL> desc meta.mta_admin
...PROCEDURE SET_IND_DAILY_APEX_REFRESH Argument Name Type In/Out Default? P_DEV_CODE VARCHAR2(10) IN P_APP_CODE VARCHAR2(10) IN P_IND_DAILY_APEX_REFRESH VARCHAR2(1) INPROCEDURE SET_IND_DAILY_DB_REFRESH Argument Name Type In/Out Default? P_DEV_CODE VARCHAR2(10) IN P_APP_CODE VARCHAR2(10) IN P_IND_DAILY_DB_REFRESH VARCHAR2(1) IN ...

62 5. Unit Testing

63 Goal Add value to the automatic build by determining if your (packaged) functions and procedures are fit to use

64

65 Development database APEX Schema META Workspace Ciber CV SCA
Workspace RWIJK SCA Workspace MPLAS CV SCA User INSTALL Schema CV_UI Schema SCA_UI Schema RWIJK_UI Schema MPLAS_UI User RWIJK Schema CV_API Schema SCA_API Schema RWIJK_API Schema MPLAS_API User MPLAS Schema CV_DATA Schema SCA_DATA Schema RWIJK_DATA Schema MPLAS_DATA Schema UT

66 A single shared test repository in schema UT
Using command line (UtUtil) a different test suite per package Schema names are included in XML definition files (Un)Load from client: UtUtil.bat & UtUtil.sh exp/imp scripts Automatic load when installing db-part of application Automatic unload when uninstalling db-part of application run all unit tests in application schema in Hudson’s nightly build manually start unit tests in developers’ schema

67 Completing Unit Testing
What’s Next? Completing Unit Testing Selenium Template project Delivering patches Sonar

68 Thanks for your attention!
@rwijk @rwijk


Download ppt "Professional Software Development using APEX"

Similar presentations


Ads by Google