disable APEX related things with conditional compilation (not done)
This commit is contained in:
parent
deb303cad9
commit
789006e4b3
@ -1,4 +1,11 @@
|
||||
prompt Installing PL/SQL Export Utilities
|
||||
set define off
|
||||
@PLEX.pks
|
||||
@PLEX.pkb
|
||||
SET DEFINE OFF
|
||||
|
||||
BEGIN
|
||||
EXECUTE IMMEDIATE q'[ alter session set plsql_ccflags='apex_exists:false' ]';
|
||||
END;
|
||||
/
|
||||
|
||||
@plex.pks
|
||||
|
||||
@plex.pkb
|
||||
51
PLEX.pkb
51
PLEX.pkb
@ -982,6 +982,8 @@ CREATE OR REPLACE PACKAGE BODY plex IS
|
||||
-- MAIN CODE
|
||||
|
||||
FUNCTION backapp (
|
||||
$if $$apex_exists $then
|
||||
|
||||
p_app_id IN NUMBER DEFAULT NULL,
|
||||
p_app_date IN BOOLEAN DEFAULT true,
|
||||
p_app_public_reports IN BOOLEAN DEFAULT true,
|
||||
@ -995,6 +997,7 @@ CREATE OR REPLACE PACKAGE BODY plex IS
|
||||
p_app_supporting_objects IN VARCHAR2 DEFAULT NULL,
|
||||
p_app_include_single_file IN BOOLEAN DEFAULT false,
|
||||
p_app_build_status_run_only IN BOOLEAN DEFAULT false,
|
||||
$end
|
||||
p_include_object_ddl IN BOOLEAN DEFAULT false,
|
||||
p_object_name_like IN VARCHAR2 DEFAULT NULL,
|
||||
p_object_name_not_like IN VARCHAR2 DEFAULT NULL,
|
||||
@ -1028,16 +1031,21 @@ CREATE OR REPLACE PACKAGE BODY plex IS
|
||||
BEGIN
|
||||
util_ilog_init(
|
||||
p_module => 'plex.backapp'
|
||||
$if $$apex_exists $then
|
||||
|
||||
|| CASE
|
||||
WHEN p_app_id IS NOT NULL THEN
|
||||
'('
|
||||
|| TO_CHAR(p_app_id)
|
||||
|| ')'
|
||||
END,
|
||||
END
|
||||
$end,
|
||||
p_include_runtime_log => p_include_runtime_log
|
||||
);
|
||||
END init;
|
||||
|
||||
$if $$apex_exists $then
|
||||
|
||||
PROCEDURE check_owner IS
|
||||
CURSOR cur_owner IS
|
||||
SELECT
|
||||
@ -1078,6 +1086,9 @@ CREATE OR REPLACE PACKAGE BODY plex IS
|
||||
|
||||
util_ilog_stop;
|
||||
END check_owner;
|
||||
$end
|
||||
|
||||
$if $$apex_exists $then
|
||||
|
||||
PROCEDURE process_apex_app IS
|
||||
l_single_file tab_export_files;
|
||||
@ -1189,16 +1200,17 @@ CREATE OR REPLACE PACKAGE BODY plex IS
|
||||
END IF;
|
||||
|
||||
END process_apex_app;
|
||||
$end
|
||||
|
||||
PROCEDURE replace_query_like_expressions (
|
||||
p_like_list VARCHAR2,
|
||||
p_not_like_list VARCHAR2,
|
||||
p_column_name VARCHAR2
|
||||
) IS
|
||||
l_expression_table apex_tab_varchar2;
|
||||
l_expression_table tab_varchar2;
|
||||
BEGIN
|
||||
-- process filter "like"
|
||||
l_expression_table := apex_string.split(
|
||||
l_expression_table := util_split(
|
||||
p_like_list,
|
||||
','
|
||||
);
|
||||
@ -1212,7 +1224,7 @@ CREATE OR REPLACE PACKAGE BODY plex IS
|
||||
l_query,
|
||||
'#LIKE_EXPRESSIONS#',
|
||||
nvl(
|
||||
apex_string.join(
|
||||
util_join(
|
||||
l_expression_table,
|
||||
' or '
|
||||
),
|
||||
@ -1222,7 +1234,7 @@ CREATE OR REPLACE PACKAGE BODY plex IS
|
||||
|
||||
-- process filter "not like"
|
||||
|
||||
l_expression_table := apex_string.split(
|
||||
l_expression_table := util_split(
|
||||
p_not_like_list,
|
||||
','
|
||||
);
|
||||
@ -1236,7 +1248,7 @@ CREATE OR REPLACE PACKAGE BODY plex IS
|
||||
l_query,
|
||||
'#NOT_LIKE_EXPRESSIONS#',
|
||||
nvl(
|
||||
apex_string.join(
|
||||
util_join(
|
||||
l_expression_table,
|
||||
' and '
|
||||
),
|
||||
@ -2083,6 +2095,8 @@ if %errorlevel% neq 0 exit /b %errorlevel%
|
||||
c_plex_url,
|
||||
'{{SYSTEMROLE}}',
|
||||
'DEV',
|
||||
$if $$apex_exists $then
|
||||
|
||||
'{{APP_ID}}',
|
||||
p_app_id,
|
||||
'{{APP_ALIAS}}',
|
||||
@ -2091,6 +2105,7 @@ if %errorlevel% neq 0 exit /b %errorlevel%
|
||||
l_app_owner,
|
||||
'{{APP_WORKSPACE}}',
|
||||
l_app_workspace,
|
||||
$end
|
||||
'{{SCRIPTFILE}}',
|
||||
'export_app_custom_code.sql',
|
||||
'{{LOGFILE}}',
|
||||
@ -2116,6 +2131,8 @@ if %errorlevel% neq 0 exit /b %errorlevel%
|
||||
c_plex_url,
|
||||
'{{SYSTEMROLE}}',
|
||||
'TEST',
|
||||
$if $$apex_exists $then
|
||||
|
||||
'{{APP_ID}}',
|
||||
p_app_id,
|
||||
'{{APP_ALIAS}}',
|
||||
@ -2124,6 +2141,7 @@ if %errorlevel% neq 0 exit /b %errorlevel%
|
||||
l_app_owner,
|
||||
'{{APP_WORKSPACE}}',
|
||||
l_app_workspace,
|
||||
$end
|
||||
'{{SCRIPTFILE}}',
|
||||
'install_app_custom_code.sql',
|
||||
'{{LOGFILE}}',
|
||||
@ -2149,6 +2167,8 @@ if %errorlevel% neq 0 exit /b %errorlevel%
|
||||
c_plex_url,
|
||||
'{{SYSTEMROLE}}',
|
||||
'PROD',
|
||||
$if $$apex_exists $then
|
||||
|
||||
'{{APP_ID}}',
|
||||
p_app_id,
|
||||
'{{APP_ALIAS}}',
|
||||
@ -2157,6 +2177,7 @@ if %errorlevel% neq 0 exit /b %errorlevel%
|
||||
l_app_owner,
|
||||
'{{APP_WORKSPACE}}',
|
||||
l_app_workspace,
|
||||
$end
|
||||
'{{SCRIPTFILE}}',
|
||||
'install_app_custom_code.sql',
|
||||
'{{LOGFILE}}',
|
||||
@ -2219,7 +2240,11 @@ DECLARE
|
||||
l_files tab_export_files;
|
||||
BEGIN
|
||||
l_files := plex.backapp (
|
||||
-- These are the defaults - align it to your needs:
|
||||
-- These are the defaults - align it to your needs:^'
|
||||
;
|
||||
$if $$apex_exists $then
|
||||
|
||||
l_file_template := l_file_template || q'^
|
||||
p_app_id => :app_id,
|
||||
p_app_date => true,
|
||||
p_app_public_reports => true,
|
||||
@ -2232,8 +2257,10 @@ BEGIN
|
||||
p_app_comments => true,
|
||||
p_app_supporting_objects => null,
|
||||
p_app_include_single_file => false,
|
||||
p_app_build_status_run_only => false,
|
||||
|
||||
p_app_build_status_run_only => false,^'
|
||||
;
|
||||
$end
|
||||
l_file_template := l_file_template || q'^
|
||||
p_include_object_ddl => true,
|
||||
p_object_name_like => null,
|
||||
p_object_name_not_like => null,
|
||||
@ -2509,13 +2536,19 @@ prompt
|
||||
|
||||
BEGIN
|
||||
init;
|
||||
$if $$apex_exists $then
|
||||
|
||||
check_owner;
|
||||
--
|
||||
IF p_app_id IS NOT NULL THEN
|
||||
process_apex_app;
|
||||
ELSE
|
||||
$end
|
||||
l_export_files := NEW tab_export_files();
|
||||
$if $$apex_exists $then
|
||||
|
||||
END IF;
|
||||
$end
|
||||
--
|
||||
|
||||
IF p_include_object_ddl THEN
|
||||
|
||||
2
PLEX.pks
2
PLEX.pks
@ -59,6 +59,7 @@ TYPE tab_varchar2 IS TABLE OF varchar2(32767);
|
||||
|
||||
|
||||
FUNCTION backapp (
|
||||
$if $$apex_exists $then
|
||||
-- App related options:
|
||||
p_app_id IN NUMBER DEFAULT null, -- If null, we simply skip the APEX app export.
|
||||
p_app_date IN BOOLEAN DEFAULT true, -- If true, include export date and time in the result.
|
||||
@ -73,6 +74,7 @@ FUNCTION backapp (
|
||||
p_app_supporting_objects IN VARCHAR2 DEFAULT null, -- If 'Y', export supporting objects. If 'I', automatically install on import. If 'N', do not export supporting objects. If null, the application's include in export deployment value is used.
|
||||
p_app_include_single_file IN BOOLEAN DEFAULT false, -- If true, the single sql install file is also included beside the splitted files.
|
||||
p_app_build_status_run_only IN BOOLEAN DEFAULT false, -- If true, the build status of the app will be overwritten to RUN_ONLY.
|
||||
$end
|
||||
-- Object related options:
|
||||
p_include_object_ddl IN BOOLEAN DEFAULT false, -- If true, include DDL of current user/schema and all its objects.
|
||||
p_object_name_like IN VARCHAR2 DEFAULT null, -- A comma separated list of like expressions to filter the objects - example: 'EMP%,DEPT%' will be translated to: where ... and (object_name like 'EMP%' escape '\' or object_name like 'DEPT%' escape '\').
|
||||
|
||||
528
lib/as_zip.sql
Normal file
528
lib/as_zip.sql
Normal file
@ -0,0 +1,528 @@
|
||||
CREATE OR REPLACE package as_zip
|
||||
is
|
||||
/**********************************************
|
||||
**
|
||||
** Author: Anton Scheffer
|
||||
** Date: 25-01-2012
|
||||
** Website: http://technology.amis.nl/blog
|
||||
**
|
||||
** Changelog:
|
||||
** Date: 04-08-2016
|
||||
** fixed endless loop for empty/null zip file
|
||||
** Date: 28-07-2016
|
||||
** added support for defate64 (this only works for zip-files created with 7Zip)
|
||||
** Date: 31-01-2014
|
||||
** file limit increased to 4GB
|
||||
** Date: 29-04-2012
|
||||
** fixed bug for large uncompressed files, thanks Morten Braten
|
||||
** Date: 21-03-2012
|
||||
** Take CRC32, compressed length and uncompressed length from
|
||||
** Central file header instead of Local file header
|
||||
** Date: 17-02-2012
|
||||
** Added more support for non-ascii filenames
|
||||
** Date: 25-01-2012
|
||||
** Added MIT-license
|
||||
** Some minor improvements
|
||||
******************************************************************************
|
||||
******************************************************************************
|
||||
Copyright (C) 2010,2011 by Anton Scheffer
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
******************************************************************************
|
||||
******************************************** */
|
||||
type file_list is table of clob;
|
||||
--
|
||||
function file2blob
|
||||
( p_dir varchar2
|
||||
, p_file_name varchar2
|
||||
)
|
||||
return blob;
|
||||
--
|
||||
function get_file_list
|
||||
( p_dir varchar2
|
||||
, p_zip_file varchar2
|
||||
, p_encoding varchar2 := null
|
||||
)
|
||||
return file_list;
|
||||
--
|
||||
function get_file_list
|
||||
( p_zipped_blob blob
|
||||
, p_encoding varchar2 := null
|
||||
)
|
||||
return file_list;
|
||||
--
|
||||
function get_file
|
||||
( p_dir varchar2
|
||||
, p_zip_file varchar2
|
||||
, p_file_name varchar2
|
||||
, p_encoding varchar2 := null
|
||||
)
|
||||
return blob;
|
||||
--
|
||||
function get_file
|
||||
( p_zipped_blob blob
|
||||
, p_file_name varchar2
|
||||
, p_encoding varchar2 := null
|
||||
)
|
||||
return blob;
|
||||
--
|
||||
procedure add1file
|
||||
( p_zipped_blob in out blob
|
||||
, p_name varchar2
|
||||
, p_content blob
|
||||
);
|
||||
--
|
||||
procedure finish_zip( p_zipped_blob in out blob );
|
||||
--
|
||||
procedure save_zip
|
||||
( p_zipped_blob blob
|
||||
, p_dir varchar2 := 'MY_DIR'
|
||||
, p_filename varchar2 := 'my.zip'
|
||||
);
|
||||
--
|
||||
/*
|
||||
declare
|
||||
g_zipped_blob blob;
|
||||
begin
|
||||
as_zip.add1file( g_zipped_blob, 'test4.txt', null ); -- a empty file
|
||||
as_zip.add1file( g_zipped_blob, 'dir1/test1.txt', utl_raw.cast_to_raw( q'<A file with some more text, stored in a subfolder which isn't added>' ) );
|
||||
as_zip.add1file( g_zipped_blob, 'test1234.txt', utl_raw.cast_to_raw( 'A small file' ) );
|
||||
as_zip.add1file( g_zipped_blob, 'dir2/', null ); -- a folder
|
||||
as_zip.add1file( g_zipped_blob, 'dir3/', null ); -- a folder
|
||||
as_zip.add1file( g_zipped_blob, 'dir3/test2.txt', utl_raw.cast_to_raw( 'A small filein a previous created folder' ) );
|
||||
as_zip.finish_zip( g_zipped_blob );
|
||||
as_zip.save_zip( g_zipped_blob, 'MY_DIR', 'my.zip' );
|
||||
dbms_lob.freetemporary( g_zipped_blob );
|
||||
end;
|
||||
--
|
||||
declare
|
||||
zip_files as_zip.file_list;
|
||||
begin
|
||||
zip_files := as_zip.get_file_list( 'MY_DIR', 'my.zip' );
|
||||
for i in zip_files.first() .. zip_files.last
|
||||
loop
|
||||
dbms_output.put_line( zip_files( i ) );
|
||||
dbms_output.put_line( utl_raw.cast_to_varchar2( as_zip.get_file( 'MY_DIR', 'my.zip', zip_files( i ) ) ) );
|
||||
end loop;
|
||||
end;
|
||||
*/
|
||||
end;
|
||||
/
|
||||
|
||||
CREATE OR REPLACE package body as_zip
|
||||
is
|
||||
--
|
||||
c_LOCAL_FILE_HEADER constant raw(4) := hextoraw( '504B0304' ); -- Local file header signature
|
||||
c_END_OF_CENTRAL_DIRECTORY constant raw(4) := hextoraw( '504B0506' ); -- End of central directory signature
|
||||
--
|
||||
function blob2num( p_blob blob, p_len integer, p_pos integer )
|
||||
return number
|
||||
is
|
||||
rv number;
|
||||
begin
|
||||
rv := utl_raw.cast_to_binary_integer( dbms_lob.substr( p_blob, p_len, p_pos ), utl_raw.little_endian );
|
||||
if rv < 0
|
||||
then
|
||||
rv := rv + 4294967296;
|
||||
end if;
|
||||
return rv;
|
||||
end;
|
||||
--
|
||||
function raw2varchar2( p_raw raw, p_encoding varchar2 )
|
||||
return varchar2
|
||||
is
|
||||
begin
|
||||
return coalesce( utl_i18n.raw_to_char( p_raw, p_encoding )
|
||||
, utl_i18n.raw_to_char( p_raw, utl_i18n.map_charset( p_encoding, utl_i18n.GENERIC_CONTEXT, utl_i18n.IANA_TO_ORACLE ) )
|
||||
);
|
||||
end;
|
||||
--
|
||||
function little_endian( p_big number, p_bytes pls_integer := 4 )
|
||||
return raw
|
||||
is
|
||||
t_big number := p_big;
|
||||
begin
|
||||
if t_big > 2147483647
|
||||
then
|
||||
t_big := t_big - 4294967296;
|
||||
end if;
|
||||
return utl_raw.substr( utl_raw.cast_from_binary_integer( t_big, utl_raw.little_endian ), 1, p_bytes );
|
||||
end;
|
||||
--
|
||||
function file2blob
|
||||
( p_dir varchar2
|
||||
, p_file_name varchar2
|
||||
)
|
||||
return blob
|
||||
is
|
||||
file_lob bfile;
|
||||
file_blob blob;
|
||||
begin
|
||||
file_lob := bfilename( p_dir, p_file_name );
|
||||
dbms_lob.open( file_lob, dbms_lob.file_readonly );
|
||||
dbms_lob.createtemporary( file_blob, true );
|
||||
dbms_lob.loadfromfile( file_blob, file_lob, dbms_lob.lobmaxsize );
|
||||
dbms_lob.close( file_lob );
|
||||
return file_blob;
|
||||
exception
|
||||
when others then
|
||||
if dbms_lob.isopen( file_lob ) = 1
|
||||
then
|
||||
dbms_lob.close( file_lob );
|
||||
end if;
|
||||
if dbms_lob.istemporary( file_blob ) = 1
|
||||
then
|
||||
dbms_lob.freetemporary( file_blob );
|
||||
end if;
|
||||
raise;
|
||||
end;
|
||||
--
|
||||
function get_file_list
|
||||
( p_zipped_blob blob
|
||||
, p_encoding varchar2 := null
|
||||
)
|
||||
return file_list
|
||||
is
|
||||
t_ind integer;
|
||||
t_hd_ind integer;
|
||||
t_rv file_list;
|
||||
t_encoding varchar2(32767);
|
||||
begin
|
||||
t_ind := nvl( dbms_lob.getlength( p_zipped_blob ), 0 ) - 21;
|
||||
loop
|
||||
exit when t_ind < 1 or dbms_lob.substr( p_zipped_blob, 4, t_ind ) = c_END_OF_CENTRAL_DIRECTORY;
|
||||
t_ind := t_ind - 1;
|
||||
end loop;
|
||||
--
|
||||
if t_ind <= 0
|
||||
then
|
||||
return null;
|
||||
end if;
|
||||
--
|
||||
t_hd_ind := blob2num( p_zipped_blob, 4, t_ind + 16 ) + 1;
|
||||
t_rv := file_list();
|
||||
t_rv.extend( blob2num( p_zipped_blob, 2, t_ind + 10 ) );
|
||||
for i in 1 .. blob2num( p_zipped_blob, 2, t_ind + 8 )
|
||||
loop
|
||||
if p_encoding is null
|
||||
then
|
||||
if utl_raw.bit_and( dbms_lob.substr( p_zipped_blob, 1, t_hd_ind + 9 ), hextoraw( '08' ) ) = hextoraw( '08' )
|
||||
then
|
||||
t_encoding := 'AL32UTF8'; -- utf8
|
||||
else
|
||||
t_encoding := 'US8PC437'; -- IBM codepage 437
|
||||
end if;
|
||||
else
|
||||
t_encoding := p_encoding;
|
||||
end if;
|
||||
t_rv( i ) := raw2varchar2
|
||||
( dbms_lob.substr( p_zipped_blob
|
||||
, blob2num( p_zipped_blob, 2, t_hd_ind + 28 )
|
||||
, t_hd_ind + 46
|
||||
)
|
||||
, t_encoding
|
||||
);
|
||||
t_hd_ind := t_hd_ind + 46
|
||||
+ blob2num( p_zipped_blob, 2, t_hd_ind + 28 ) -- File name length
|
||||
+ blob2num( p_zipped_blob, 2, t_hd_ind + 30 ) -- Extra field length
|
||||
+ blob2num( p_zipped_blob, 2, t_hd_ind + 32 ); -- File comment length
|
||||
end loop;
|
||||
--
|
||||
return t_rv;
|
||||
end;
|
||||
--
|
||||
function get_file_list
|
||||
( p_dir varchar2
|
||||
, p_zip_file varchar2
|
||||
, p_encoding varchar2 := null
|
||||
)
|
||||
return file_list
|
||||
is
|
||||
begin
|
||||
return get_file_list( file2blob( p_dir, p_zip_file ), p_encoding );
|
||||
end;
|
||||
--
|
||||
function get_file
|
||||
( p_zipped_blob blob
|
||||
, p_file_name varchar2
|
||||
, p_encoding varchar2 := null
|
||||
)
|
||||
return blob
|
||||
is
|
||||
t_tmp blob;
|
||||
t_ind integer;
|
||||
t_hd_ind integer;
|
||||
t_fl_ind integer;
|
||||
t_encoding varchar2(32767);
|
||||
t_len integer;
|
||||
begin
|
||||
t_ind := nvl( dbms_lob.getlength( p_zipped_blob ), 0 ) - 21;
|
||||
loop
|
||||
exit when t_ind < 1 or dbms_lob.substr( p_zipped_blob, 4, t_ind ) = c_END_OF_CENTRAL_DIRECTORY;
|
||||
t_ind := t_ind - 1;
|
||||
end loop;
|
||||
--
|
||||
if t_ind <= 0
|
||||
then
|
||||
return null;
|
||||
end if;
|
||||
--
|
||||
t_hd_ind := blob2num( p_zipped_blob, 4, t_ind + 16 ) + 1;
|
||||
for i in 1 .. blob2num( p_zipped_blob, 2, t_ind + 8 )
|
||||
loop
|
||||
if p_encoding is null
|
||||
then
|
||||
if utl_raw.bit_and( dbms_lob.substr( p_zipped_blob, 1, t_hd_ind + 9 ), hextoraw( '08' ) ) = hextoraw( '08' )
|
||||
then
|
||||
t_encoding := 'AL32UTF8'; -- utf8
|
||||
else
|
||||
t_encoding := 'US8PC437'; -- IBM codepage 437
|
||||
end if;
|
||||
else
|
||||
t_encoding := p_encoding;
|
||||
end if;
|
||||
if p_file_name = raw2varchar2
|
||||
( dbms_lob.substr( p_zipped_blob
|
||||
, blob2num( p_zipped_blob, 2, t_hd_ind + 28 )
|
||||
, t_hd_ind + 46
|
||||
)
|
||||
, t_encoding
|
||||
)
|
||||
then
|
||||
t_len := blob2num( p_zipped_blob, 4, t_hd_ind + 24 ); -- uncompressed length
|
||||
if t_len = 0
|
||||
then
|
||||
if substr( p_file_name, -1 ) in ( '/', '\' )
|
||||
then -- directory/folder
|
||||
return null;
|
||||
else -- empty file
|
||||
return empty_blob();
|
||||
end if;
|
||||
end if;
|
||||
--
|
||||
if dbms_lob.substr( p_zipped_blob, 2, t_hd_ind + 10 ) in ( hextoraw( '0800' ) -- deflate
|
||||
, hextoraw( '0900' ) -- deflate64
|
||||
)
|
||||
then
|
||||
t_fl_ind := blob2num( p_zipped_blob, 4, t_hd_ind + 42 );
|
||||
t_tmp := hextoraw( '1F8B0800000000000003' ); -- gzip header
|
||||
dbms_lob.copy( t_tmp
|
||||
, p_zipped_blob
|
||||
, blob2num( p_zipped_blob, 4, t_hd_ind + 20 )
|
||||
, 11
|
||||
, t_fl_ind + 31
|
||||
+ blob2num( p_zipped_blob, 2, t_fl_ind + 27 ) -- File name length
|
||||
+ blob2num( p_zipped_blob, 2, t_fl_ind + 29 ) -- Extra field length
|
||||
);
|
||||
dbms_lob.append( t_tmp, utl_raw.concat( dbms_lob.substr( p_zipped_blob, 4, t_hd_ind + 16 ) -- CRC32
|
||||
, little_endian( t_len ) -- uncompressed length
|
||||
)
|
||||
);
|
||||
return utl_compress.lz_uncompress( t_tmp );
|
||||
end if;
|
||||
--
|
||||
if dbms_lob.substr( p_zipped_blob, 2, t_hd_ind + 10 ) = hextoraw( '0000' ) -- The file is stored (no compression)
|
||||
then
|
||||
t_fl_ind := blob2num( p_zipped_blob, 4, t_hd_ind + 42 );
|
||||
dbms_lob.createtemporary( t_tmp, true );
|
||||
dbms_lob.copy( t_tmp
|
||||
, p_zipped_blob
|
||||
, t_len
|
||||
, 1
|
||||
, t_fl_ind + 31
|
||||
+ blob2num( p_zipped_blob, 2, t_fl_ind + 27 ) -- File name length
|
||||
+ blob2num( p_zipped_blob, 2, t_fl_ind + 29 ) -- Extra field length
|
||||
);
|
||||
return t_tmp;
|
||||
end if;
|
||||
end if;
|
||||
t_hd_ind := t_hd_ind + 46
|
||||
+ blob2num( p_zipped_blob, 2, t_hd_ind + 28 ) -- File name length
|
||||
+ blob2num( p_zipped_blob, 2, t_hd_ind + 30 ) -- Extra field length
|
||||
+ blob2num( p_zipped_blob, 2, t_hd_ind + 32 ); -- File comment length
|
||||
end loop;
|
||||
--
|
||||
return null;
|
||||
end;
|
||||
--
|
||||
function get_file
|
||||
( p_dir varchar2
|
||||
, p_zip_file varchar2
|
||||
, p_file_name varchar2
|
||||
, p_encoding varchar2 := null
|
||||
)
|
||||
return blob
|
||||
is
|
||||
begin
|
||||
return get_file( file2blob( p_dir, p_zip_file ), p_file_name, p_encoding );
|
||||
end;
|
||||
--
|
||||
procedure add1file
|
||||
( p_zipped_blob in out blob
|
||||
, p_name varchar2
|
||||
, p_content blob
|
||||
)
|
||||
is
|
||||
t_now date;
|
||||
t_blob blob;
|
||||
t_len integer;
|
||||
t_clen integer;
|
||||
t_crc32 raw(4) := hextoraw( '00000000' );
|
||||
t_compressed boolean := false;
|
||||
t_name raw(32767);
|
||||
begin
|
||||
t_now := sysdate;
|
||||
t_len := nvl( dbms_lob.getlength( p_content ), 0 );
|
||||
if t_len > 0
|
||||
then
|
||||
t_blob := utl_compress.lz_compress( p_content );
|
||||
t_clen := dbms_lob.getlength( t_blob ) - 18;
|
||||
t_compressed := t_clen < t_len;
|
||||
t_crc32 := dbms_lob.substr( t_blob, 4, t_clen + 11 );
|
||||
end if;
|
||||
if not t_compressed
|
||||
then
|
||||
t_clen := t_len;
|
||||
t_blob := p_content;
|
||||
end if;
|
||||
if p_zipped_blob is null
|
||||
then
|
||||
dbms_lob.createtemporary( p_zipped_blob, true );
|
||||
end if;
|
||||
t_name := utl_i18n.string_to_raw( p_name, 'AL32UTF8' );
|
||||
dbms_lob.append( p_zipped_blob
|
||||
, utl_raw.concat( c_LOCAL_FILE_HEADER -- Local file header signature
|
||||
, hextoraw( '1400' ) -- version 2.0
|
||||
, case when t_name = utl_i18n.string_to_raw( p_name, 'US8PC437' )
|
||||
then hextoraw( '0000' ) -- no General purpose bits
|
||||
else hextoraw( '0008' ) -- set Language encoding flag (EFS)
|
||||
end
|
||||
, case when t_compressed
|
||||
then hextoraw( '0800' ) -- deflate
|
||||
else hextoraw( '0000' ) -- stored
|
||||
end
|
||||
, little_endian( to_number( to_char( t_now, 'ss' ) ) / 2
|
||||
+ to_number( to_char( t_now, 'mi' ) ) * 32
|
||||
+ to_number( to_char( t_now, 'hh24' ) ) * 2048
|
||||
, 2
|
||||
) -- File last modification time
|
||||
, little_endian( to_number( to_char( t_now, 'dd' ) )
|
||||
+ to_number( to_char( t_now, 'mm' ) ) * 32
|
||||
+ ( to_number( to_char( t_now, 'yyyy' ) ) - 1980 ) * 512
|
||||
, 2
|
||||
) -- File last modification date
|
||||
, t_crc32 -- CRC-32
|
||||
, little_endian( t_clen ) -- compressed size
|
||||
, little_endian( t_len ) -- uncompressed size
|
||||
, little_endian( utl_raw.length( t_name ), 2 ) -- File name length
|
||||
, hextoraw( '0000' ) -- Extra field length
|
||||
, t_name -- File name
|
||||
)
|
||||
);
|
||||
if t_compressed
|
||||
then
|
||||
dbms_lob.copy( p_zipped_blob, t_blob, t_clen, dbms_lob.getlength( p_zipped_blob ) + 1, 11 ); -- compressed content
|
||||
elsif t_clen > 0
|
||||
then
|
||||
dbms_lob.copy( p_zipped_blob, t_blob, t_clen, dbms_lob.getlength( p_zipped_blob ) + 1, 1 ); -- content
|
||||
end if;
|
||||
if dbms_lob.istemporary( t_blob ) = 1
|
||||
then
|
||||
dbms_lob.freetemporary( t_blob );
|
||||
end if;
|
||||
end;
|
||||
--
|
||||
procedure finish_zip( p_zipped_blob in out blob )
|
||||
is
|
||||
t_cnt pls_integer := 0;
|
||||
t_offs integer;
|
||||
t_offs_dir_header integer;
|
||||
t_offs_end_header integer;
|
||||
t_comment raw(32767) := utl_raw.cast_to_raw( 'Implementation by Anton Scheffer' );
|
||||
begin
|
||||
t_offs_dir_header := dbms_lob.getlength( p_zipped_blob );
|
||||
t_offs := 1;
|
||||
while dbms_lob.substr( p_zipped_blob, utl_raw.length( c_LOCAL_FILE_HEADER ), t_offs ) = c_LOCAL_FILE_HEADER
|
||||
loop
|
||||
t_cnt := t_cnt + 1;
|
||||
dbms_lob.append( p_zipped_blob
|
||||
, utl_raw.concat( hextoraw( '504B0102' ) -- Central directory file header signature
|
||||
, hextoraw( '1400' ) -- version 2.0
|
||||
, dbms_lob.substr( p_zipped_blob, 26, t_offs + 4 )
|
||||
, hextoraw( '0000' ) -- File comment length
|
||||
, hextoraw( '0000' ) -- Disk number where file starts
|
||||
, hextoraw( '0000' ) -- Internal file attributes =>
|
||||
-- 0000 binary file
|
||||
-- 0100 (ascii)text file
|
||||
, case
|
||||
when dbms_lob.substr( p_zipped_blob
|
||||
, 1
|
||||
, t_offs + 30 + blob2num( p_zipped_blob, 2, t_offs + 26 ) - 1
|
||||
) in ( hextoraw( '2F' ) -- /
|
||||
, hextoraw( '5C' ) -- \
|
||||
)
|
||||
then hextoraw( '10000000' ) -- a directory/folder
|
||||
else hextoraw( '2000B681' ) -- a file
|
||||
end -- External file attributes
|
||||
, little_endian( t_offs - 1 ) -- Relative offset of local file header
|
||||
, dbms_lob.substr( p_zipped_blob
|
||||
, blob2num( p_zipped_blob, 2, t_offs + 26 )
|
||||
, t_offs + 30
|
||||
) -- File name
|
||||
)
|
||||
);
|
||||
t_offs := t_offs + 30 + blob2num( p_zipped_blob, 4, t_offs + 18 ) -- compressed size
|
||||
+ blob2num( p_zipped_blob, 2, t_offs + 26 ) -- File name length
|
||||
+ blob2num( p_zipped_blob, 2, t_offs + 28 ); -- Extra field length
|
||||
end loop;
|
||||
t_offs_end_header := dbms_lob.getlength( p_zipped_blob );
|
||||
dbms_lob.append( p_zipped_blob
|
||||
, utl_raw.concat( c_END_OF_CENTRAL_DIRECTORY -- End of central directory signature
|
||||
, hextoraw( '0000' ) -- Number of this disk
|
||||
, hextoraw( '0000' ) -- Disk where central directory starts
|
||||
, little_endian( t_cnt, 2 ) -- Number of central directory records on this disk
|
||||
, little_endian( t_cnt, 2 ) -- Total number of central directory records
|
||||
, little_endian( t_offs_end_header - t_offs_dir_header ) -- Size of central directory
|
||||
, little_endian( t_offs_dir_header ) -- Offset of start of central directory, relative to start of archive
|
||||
, little_endian( nvl( utl_raw.length( t_comment ), 0 ), 2 ) -- ZIP file comment length
|
||||
, t_comment
|
||||
)
|
||||
);
|
||||
end;
|
||||
--
|
||||
procedure save_zip
|
||||
( p_zipped_blob blob
|
||||
, p_dir varchar2 := 'MY_DIR'
|
||||
, p_filename varchar2 := 'my.zip'
|
||||
)
|
||||
is
|
||||
t_fh utl_file.file_type;
|
||||
t_len pls_integer := 32767;
|
||||
begin
|
||||
t_fh := utl_file.fopen( p_dir, p_filename, 'wb' );
|
||||
for i in 0 .. trunc( ( dbms_lob.getlength( p_zipped_blob ) - 1 ) / t_len )
|
||||
loop
|
||||
utl_file.put_raw( t_fh, dbms_lob.substr( p_zipped_blob, t_len, i * t_len + 1 ) );
|
||||
end loop;
|
||||
utl_file.fclose( t_fh );
|
||||
end;
|
||||
--
|
||||
end;
|
||||
/
|
||||
1
lib/as_zip.txt
Normal file
1
lib/as_zip.txt
Normal file
@ -0,0 +1 @@
|
||||
https://technology.amis.nl/2010/03/13/utl_compress-gzip-and-zlib/
|
||||
Loading…
x
Reference in New Issue
Block a user