From 3c63b278d013cb1a47dd63f020620354cc00cead Mon Sep 17 00:00:00 2001 From: Eric Olson Date: Mon, 4 Jan 2016 18:54:56 -0600 Subject: [PATCH 1/9] Change XPath for get_item Id and ChangeKey are attributes. --- ora/ms_ews_util_pkg.pkb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ora/ms_ews_util_pkg.pkb b/ora/ms_ews_util_pkg.pkb index 80f65bd..9155392 100755 --- a/ora/ms_ews_util_pkg.pkb +++ b/ora/ms_ews_util_pkg.pkb @@ -831,8 +831,8 @@ begin -- general Item info l_returnvalue.sequence_number := 1; - l_returnvalue.item_id := flex_ws_api.parse_xml(l_xml, '//*/t:ItemId/@Id/text()', g_namespace_messages || ' ' || g_namespace_types); - l_returnvalue.change_key := flex_ws_api.parse_xml(l_xml, '//*/t:ItemId/@ChangeKey/text()', g_namespace_messages || ' ' || g_namespace_types); + l_returnvalue.item_id := flex_ws_api.parse_xml(l_xml, '//*/t:ItemId/@Id', g_namespace_messages || ' ' || g_namespace_types); + l_returnvalue.change_key := flex_ws_api.parse_xml(l_xml, '//*/t:ItemId/@ChangeKey', g_namespace_messages || ' ' || g_namespace_types); l_returnvalue.item_size := to_number(flex_ws_api.parse_xml(l_xml, '//*/t:Size/text()', g_namespace_messages || ' ' || g_namespace_types)); l_returnvalue.subject := flex_ws_api.parse_xml(l_xml, '//*/t:Subject/text()', g_namespace_messages || ' ' || g_namespace_types); From 18985e2c127b2b2ef30d238c925feddfac87826c Mon Sep 17 00:00:00 2001 From: datRedHeadedGuy Date: Fri, 4 Mar 2016 16:18:44 -0600 Subject: [PATCH 2/9] Update ooxml_util_pkg.pkb Added a new function within the ooxml_util_pkg body that will return a collection of the worksheet records that include the name of the worksheet, the sheet ID of the worksheet, and the relationship ID for the worksheet. This will allow for the ability to look-up worksheets and parse them without needing to know what the worksheet's name is in advance. --- ora/ooxml_util_pkg.pkb | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/ora/ooxml_util_pkg.pkb b/ora/ooxml_util_pkg.pkb index 97e7365..4be543e 100755 --- a/ora/ooxml_util_pkg.pkb +++ b/ora/ooxml_util_pkg.pkb @@ -58,6 +58,44 @@ begin end get_xml; +function get_worksheets_list( p_xlsx in blob ) return t_xlsx_sheet_properties +as + l_returnvalue t_xlsx_sheet_properties; + l_xml xmltype; +begin + + /* + + Purpose: get an array of the worksheets in the workbook + + Remarks: + + Who Date Description + ------ ---------- -------------------------------- + JMW 02.03.2016 Created + + */ + + l_xml := get_xml( p_xlsx, 'xl/workbook.xml' ); + + select xml.r_id, xml.sheetid, xml.name + bulk collect into l_returnvalue + from xmltable( xmlnamespaces( default 'http://schemas.openxmlformats.org/spreadsheetml/2006/main', + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' AS "r" ), + '/workbook/sheets/sheet' + passing l_xml + columns + r_id varchar2(255) path '@r:id', + sheetid number path '@sheetId', + name varchar2(31) path '@name' ) xml + where xml.r_id is not null + order by xml.sheetid; + + return l_returnvalue; + +end get_worksheets_list; + + function get_docx_properties (p_docx in blob) return t_docx_properties as l_returnvalue t_docx_properties; From f671dd16ebafec5c4976aaf897943d228c41b66b Mon Sep 17 00:00:00 2001 From: datRedHeadedGuy Date: Fri, 4 Mar 2016 16:24:00 -0600 Subject: [PATCH 3/9] Update ooxml_util_pkg.pks Added a new function within the ooxml_util_pkg specifications that will return a collection of the worksheet records that include the name of the worksheet, the sheet ID of the worksheet, and the relationship ID for the worksheet. This will allow for the ability to look-up worksheets and parse them without needing to know what the worksheet's name is in advance. --- ora/ooxml_util_pkg.pks | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/ora/ooxml_util_pkg.pks b/ora/ooxml_util_pkg.pks index 2fba608..241ba6c 100755 --- a/ora/ooxml_util_pkg.pks +++ b/ora/ooxml_util_pkg.pks @@ -77,7 +77,18 @@ as ); type t_xlsx_sheet is table of t_xlsx_cell index by varchar2(20); - + + type t_xlsx_sheet_attributes is record ( + r_id varchar2(255), + sheetid number, + name varchar2(31) + ); + + type t_xlsx_sheet_properties is table of t_xlsx_sheet_attributes index by pls_integer; + + -- get list of xlsx worksheets + function get_worksheets_list( p_xlsx in blob ) return t_xlsx_sheet_properties; + -- get docx properties function get_docx_properties (p_docx in blob) return t_docx_properties; From 3e8c6b0f1090808655bc7e230b630a64f80e0290 Mon Sep 17 00:00:00 2001 From: Tim Nanos Date: Fri, 1 Apr 2016 14:48:25 +0300 Subject: [PATCH 4/9] Email validation was changed to follow RFC 5322 standard The email regexp was improved to be case-insensitive. Old is_valid_email() function was removed. is_valid_email2() function was renamed to is_valid_email() in order to be more user-friendly. Code readability was improved. --- ora/regexp_util_pkg.pks | 2 +- ora/validation_util_pkg.pkb | 80 ++++++------------------------------- ora/validation_util_pkg.pks | 3 -- 3 files changed, 13 insertions(+), 72 deletions(-) diff --git a/ora/regexp_util_pkg.pks b/ora/regexp_util_pkg.pks index 74d27e5..644e848 100755 --- a/ora/regexp_util_pkg.pks +++ b/ora/regexp_util_pkg.pks @@ -16,7 +16,7 @@ as g_exp_bind_vars constant varchar2(255) := ':\w+'; g_exp_hyperlinks constant varchar2(255) := '[^<]+'; g_exp_ip_addresses constant varchar2(255) := '(\d{1,3}\.){3}\d{1,3}'; - g_exp_email_addresses constant varchar2(255) := '[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}'; + g_exp_email_addresses constant varchar2(255) := '^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$'; g_exp_email_address_list constant varchar2(255) := '^((\s*[a-zA-Z0-9\._%-]+@[a-zA-Z0-9\.-]+\.[a-zA-Z]{2,4}\s*[,;:]){1,100}?)?(\s*[a-zA-Z0-9\._%-]+@[a-zA-Z0-9\.-]+\.[a-zA-Z]{2,4})*$'; g_exp_double_words constant varchar2(255) := ' ([A-Za-z]+) \1'; g_exp_cc_visa constant varchar2(255) := '^4[0-9]{12}(?:[0-9]{3})?$'; diff --git a/ora/validation_util_pkg.pkb b/ora/validation_util_pkg.pkb index b8738bd..38c8239 100755 --- a/ora/validation_util_pkg.pkb +++ b/ora/validation_util_pkg.pkb @@ -12,59 +12,9 @@ as MBR 23.10.2011 Created */ - - + + function is_valid_email (p_value in varchar2) return boolean -as - l_dot_pos number; - l_at_pos number; - l_str_length number; - l_returnvalue boolean := true; -begin - - /* - - Purpose: returns true if value is valid email address - - Remarks: Written by Anil Passi, see http://oracle.anilpassi.com/validate-email-pl-sql-2.html - - Who Date Description - ------ ---------- -------------------------------- - MBR 23.10.2011 Created - MBR 26.10.2011 Added check against multiple at signs - - */ - - if p_value is null then - l_returnvalue := false; - else - - l_dot_pos := instr(p_value, '.'); - l_at_pos := instr(p_value, '@'); - - l_str_length := length(p_value); - - if ((l_dot_pos = 0) or (l_at_pos = 0) or (l_dot_pos = l_at_pos + 1) or (l_at_pos = 1) or (l_at_pos = l_str_length) or (l_dot_pos = l_str_length)) then - l_returnvalue := false; - end if; - - if instr(substr(p_value, l_at_pos), '.') = 0 then - l_returnvalue := false; - end if; - - if instr(substr(p_value, l_at_pos + 1), '@') > 0 then - l_returnvalue := false; - end if; - - - end if; - - return l_returnvalue; - -end is_valid_email; - - -function is_valid_email2 (p_value in varchar2) return boolean as l_value varchar2(32000); l_returnvalue boolean; @@ -79,18 +29,15 @@ begin Who Date Description ------ ---------- -------------------------------- MBR 23.10.2011 Created + Tim N 01.04.2016 Enhancements */ - - if p_value is null then - l_returnvalue := false; - else - l_returnvalue := regexp_replace(p_value, regexp_util_pkg.g_exp_email_addresses, null) is null; - end if; - + + l_returnvalue := regexp_like(p_value, regexp_util_pkg.g_exp_email_addresses); + return l_returnvalue; - -end is_valid_email2; + +end is_valid_email; function is_valid_email_list (p_value in varchar2) return boolean @@ -107,17 +54,14 @@ begin Who Date Description ------ ---------- -------------------------------- MBR 23.10.2011 Created + Tim N 01.04.2016 Enhancements */ - - if p_value is null then - l_returnvalue := false; - else - l_returnvalue := regexp_replace(p_value, regexp_util_pkg.g_exp_email_address_list, null) is null; - end if; + + l_returnvalue := regexp_like(p_value, regexp_util_pkg.g_exp_email_address_list); return l_returnvalue; - + end is_valid_email_list; diff --git a/ora/validation_util_pkg.pks b/ora/validation_util_pkg.pks index 60450ff..e0a3330 100755 --- a/ora/validation_util_pkg.pks +++ b/ora/validation_util_pkg.pks @@ -17,9 +17,6 @@ as -- returns true if value is valid email address function is_valid_email (p_value in varchar2) return boolean; - -- returns true if value is valid email address - function is_valid_email2 (p_value in varchar2) return boolean; - -- returns true if value is valid email address list function is_valid_email_list (p_value in varchar2) return boolean; From e618894a6ab77fbd156eb1c011b50ade1e5d568b Mon Sep 17 00:00:00 2001 From: Tim Nanos Date: Mon, 4 Apr 2016 17:56:16 +0300 Subject: [PATCH 5/9] Function is_valid_email2() was returned for the backward compatibility --- ora/validation_util_pkg.pks | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ora/validation_util_pkg.pks b/ora/validation_util_pkg.pks index e0a3330..80438a1 100755 --- a/ora/validation_util_pkg.pks +++ b/ora/validation_util_pkg.pks @@ -17,6 +17,9 @@ as -- returns true if value is valid email address function is_valid_email (p_value in varchar2) return boolean; + -- returns true if value is valid email address + function is_valid_email2 (p_value in varchar2) return boolean; + -- returns true if value is valid email address list function is_valid_email_list (p_value in varchar2) return boolean; From e46bb1c3bd4460676350511afe782a2b078ea2b5 Mon Sep 17 00:00:00 2001 From: Tim Nanos Date: Mon, 4 Apr 2016 17:59:53 +0300 Subject: [PATCH 6/9] Function is_valid_email2() was returned for the backward compatibility --- ora/validation_util_pkg.pkb | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/ora/validation_util_pkg.pkb b/ora/validation_util_pkg.pkb index 38c8239..e286e09 100755 --- a/ora/validation_util_pkg.pkb +++ b/ora/validation_util_pkg.pkb @@ -38,7 +38,22 @@ begin return l_returnvalue; end is_valid_email; + + +function is_valid_email2 (p_value in varchar2) return boolean +as +begin + + /* + Purpose: backward compatibility only + + */ + + return is_valid_email(p_value); + +end is_valid_email2; + function is_valid_email_list (p_value in varchar2) return boolean as From 7785c334d197e4c95d1e4f70033fbfaba767029a Mon Sep 17 00:00:00 2001 From: Eric Olson Date: Wed, 20 Apr 2016 18:51:11 -0500 Subject: [PATCH 7/9] Fix Id attribute in a few other places --- ora/ms_ews_util_pkg.pkb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ora/ms_ews_util_pkg.pkb b/ora/ms_ews_util_pkg.pkb index 9155392..6aad749 100755 --- a/ora/ms_ews_util_pkg.pkb +++ b/ora/ms_ews_util_pkg.pkb @@ -522,7 +522,7 @@ begin l_xml := make_request (l_soap_action, get_request_envelope); l_returnvalue.sequence_number := 1; - l_returnvalue.folder_id := flex_ws_api.parse_xml(l_xml, '//*/t:FolderId/@Id/text()', g_namespace_messages || ' ' || g_namespace_types); + l_returnvalue.folder_id := flex_ws_api.parse_xml(l_xml, '//*/t:FolderId/@Id', g_namespace_messages || ' ' || g_namespace_types); l_returnvalue.display_name := flex_ws_api.parse_xml(l_xml, '//*/t:DisplayName/text()', g_namespace_messages || ' ' || g_namespace_types); l_returnvalue.total_count := to_number(flex_ws_api.parse_xml(l_xml, '//*/t:TotalCount/text()', g_namespace_messages || ' ' || g_namespace_types)); l_returnvalue.child_folder_count := to_number(flex_ws_api.parse_xml(l_xml, '//*/t:ChildFolderCount/text()', g_namespace_messages || ' ' || g_namespace_types)); @@ -1209,7 +1209,7 @@ begin l_xml := make_request (l_soap_action, get_request_envelope); -- TODO: verify that ID is returned/parsed... - l_returnvalue := flex_ws_api.parse_xml(l_xml, '//*/m:Items/t:CalendarItem/t:ItemId/@Id/text()', g_namespace_messages || ' ' || g_namespace_types); + l_returnvalue := flex_ws_api.parse_xml(l_xml, '//*/m:Items/t:CalendarItem/t:ItemId/@Id', g_namespace_messages || ' ' || g_namespace_types); return l_returnvalue; @@ -1278,7 +1278,7 @@ begin l_xml := make_request (l_soap_action, get_request_envelope); -- TODO: verify that ID is returned/parsed... - l_returnvalue := flex_ws_api.parse_xml(l_xml, '//*/m:Items/t:Task/t:ItemId/@Id/text()', g_namespace_messages || ' ' || g_namespace_types); + l_returnvalue := flex_ws_api.parse_xml(l_xml, '//*/m:Items/t:Task/t:ItemId/@Id', g_namespace_messages || ' ' || g_namespace_types); return l_returnvalue; @@ -1376,7 +1376,7 @@ begin l_xml := make_request (l_soap_action, get_request_envelope); -- TODO: verify that ID is returned/parsed... - l_returnvalue := flex_ws_api.parse_xml(l_xml, '//*/m:Items/t:Message/t:ItemId/@Id/text()', g_namespace_messages || ' ' || g_namespace_types); + l_returnvalue := flex_ws_api.parse_xml(l_xml, '//*/m:Items/t:Message/t:ItemId/@Id', g_namespace_messages || ' ' || g_namespace_types); return l_returnvalue; @@ -1633,7 +1633,7 @@ begin l_xml := make_request (l_soap_action, get_request_envelope); - l_returnvalue.attachment_id := flex_ws_api.parse_xml(l_xml, '//*/m:Attachments/t:FileAttachment/t:AttachmentId/@Id/text()', g_namespace_messages || ' ' || g_namespace_types); + l_returnvalue.attachment_id := flex_ws_api.parse_xml(l_xml, '//*/m:Attachments/t:FileAttachment/t:AttachmentId/@Id', g_namespace_messages || ' ' || g_namespace_types); l_returnvalue.name := flex_ws_api.parse_xml(l_xml, '//*/m:Attachments/t:FileAttachment/t:Name/text()', g_namespace_messages || ' ' || g_namespace_types); l_returnvalue.content_type := flex_ws_api.parse_xml(l_xml, '//*/m:Attachments/t:FileAttachment/t:ContentType/text()', g_namespace_messages || ' ' || g_namespace_types); l_returnvalue.content_id := flex_ws_api.parse_xml(l_xml, '//*/m:Attachments/t:FileAttachment/t:ContentId/text()', g_namespace_messages || ' ' || g_namespace_types); @@ -1706,7 +1706,7 @@ begin l_xml := make_request (l_soap_action, get_request_envelope); -- TODO: verify that value is returned... - l_returnvalue := flex_ws_api.parse_xml(l_xml, '//*/m:Attachments/t:FileAttachment/t:AttachmentId/@Id/text()', g_namespace_messages || ' ' || g_namespace_types); + l_returnvalue := flex_ws_api.parse_xml(l_xml, '//*/m:Attachments/t:FileAttachment/t:AttachmentId/@Id', g_namespace_messages || ' ' || g_namespace_types); return l_returnvalue; From 2583ce7127cb283dfd9e2d0e1aa4f6eaf8fa3660 Mon Sep 17 00:00:00 2001 From: David Gale Date: Tue, 3 May 2016 12:14:16 -0400 Subject: [PATCH 8/9] Update ooxml_util_pkg.pkb Added the ability for get_file_from_template to update the notes of a PowerPoint slide in addition to the content. --- ora/ooxml_util_pkg.pkb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ora/ooxml_util_pkg.pkb b/ora/ooxml_util_pkg.pkb index 4be543e..cff309e 100755 --- a/ora/ooxml_util_pkg.pkb +++ b/ora/ooxml_util_pkg.pkb @@ -246,7 +246,9 @@ begin l_blob := zip_util_pkg.get_file (p_template, l_file_list(i)); - if l_file_list(i) in ('word/document.xml', 'word/footer1.xml', 'xl/sharedStrings.xml') or (l_file_list(i) like 'ppt/slides/slide%.xml') then + if l_file_list(i) in ('word/document.xml', 'word/footer1.xml', 'xl/sharedStrings.xml') + or (l_file_list(i) like 'ppt/slides/slide%.xml') + or (l_file_list(i) like 'ppt/notesSlides/notesSlide%.xml') then l_clob := sql_util_pkg.blob_to_clob (l_blob); l_clob := string_util_pkg.multi_replace (l_clob, p_names, p_values); From ae8f2d2058b15a36355f2d16d3deb336a30d13e7 Mon Sep 17 00:00:00 2001 From: tompetrus Date: Fri, 20 May 2016 16:29:56 +0200 Subject: [PATCH 9/9] Bugfix add1xml When the length of p_xml would be an exact multitude of 4000 the loop over chunks would execute one time too much, causing "ORA-06502: PLSQL: numeric of value error: invalid LOB locator specified: ORA-22275", because the second part of dbms_lob.append would be NULL. A check is added on the length of the clob and if if the mod of 4000 is zero, we decrease the amount of loops by one. --- ora/xlsx_builder_pkg.pkb | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/ora/xlsx_builder_pkg.pkb b/ora/xlsx_builder_pkg.pkb index 064c19b..ae28410 100755 --- a/ora/xlsx_builder_pkg.pkb +++ b/ora/xlsx_builder_pkg.pkb @@ -774,22 +774,29 @@ as workbook.sheets( t_sheet ).autofilters( t_ind ).row_end := p_row_end; end; -- - procedure add1xml - ( p_excel in out nocopy blob - , p_filename varchar2 - , p_xml clob - ) - is + procedure add1xml + ( p_excel in out nocopy blob + , p_filename varchar2 + , p_xml clob + ) + is t_tmp blob; - begin + l_count binary_integer; + begin dbms_lob.createtemporary( t_tmp, true ); - for i in 0 .. trunc( length( p_xml ) / 4000 ) - loop - dbms_lob.append( t_tmp, utl_i18n.string_to_raw( substr( p_xml, i * 4000 + 1, 4000 ), 'AL32UTF8' ) ); - end loop; - add1file( p_excel, p_filename, t_tmp ); - dbms_lob.freetemporary( t_tmp ); - end; + l_count := trunc( length( p_xml ) / 4000 ); + + if mod( length( p_xml ), 4000 ) = 0 then + l_count := greatest(l_count - 1, 0); + end if; + + for i in 0 .. l_count + loop + dbms_lob.append( t_tmp, utl_i18n.string_to_raw( substr( p_xml, i * 4000 + 1, 4000 ), 'AL32UTF8') ); + end loop; + add1file( p_excel, p_filename, t_tmp ); + dbms_lob.freetemporary( t_tmp ); + end; -- function finish return blob