Merge pull request #3 from ogobrecht/development

New version from development branch
This commit is contained in:
Ottmar Gobrecht 2019-12-30 21:38:51 +01:00 committed by GitHub
commit 69c2cfbbea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 6663 additions and 3082 deletions

1
.gitattributes vendored Normal file
View File

@ -0,0 +1 @@
*.sql linguist-language=PLSQL

8
.gitignore vendored
View File

@ -1,7 +1,3 @@
node_modules
temp
demo.sql
L_XE*.sql
*.zip
plex_install_SYS.bat
plex_install_APEX_190100.bat
node_modules
test_export

425
README.md
View File

@ -1,23 +1,24 @@
<!-- DO NOT EDIT THIS FILE DIRECTLY - it is generated from source file PLEX.pks -->
<!-- DO NOT EDIT THIS FILE DIRECTLY - it is generated from source file src/PLEX.pks -->
PL/SQL Export Utilities
=======================
=======================
- [Package PLEX](#plex)
- [Function backapp](#backapp)
- [Procedure add_query](#add_query)
- [Function queries_to_csv](#queries_to_csv)
- [Function to_zip](#to_zip)
- [Function to_base64](#to_base64)
- [Function view_error_log](#view_error_log)
- [Function view_runtime_log](#view_runtime_log)
<h2><a id="plex"></a>Package PLEX</h2>
<!----------------------------------->
PLEX was created to be able to quickstart version control for existing Oracle DB projects and has currently two main functions called **BackApp** and **Queries_to_CSV**. Queries_to_CSV is used by BackApp as a helper function, but its functionality is also useful standalone.
- [Package PLEX](#plex)
- [Function backapp](#backapp)
- [Procedure add_query](#add_query)
- [Function queries_to_csv](#queries_to_csv)
- [Function to_zip](#to_zip)
- [Function view_error_log](#view_error_log)
- [Function view_runtime_log](#view_runtime_log)
<h2><a id="plex"></a>Package PLEX</h2>
<!----------------------------------->
PLEX was created to be able to quickstart version control for existing (APEX) apps and has currently two main functions called **BackApp** and **Queries_to_CSV**. Queries_to_CSV is used by BackApp as a helper function, but its functionality is also useful standalone.
See also this resources for more information:
Also see this resources for more information:
- [Blog post on how to getting started](https://ogobrecht.github.io/posts/2018-08-26-plex-plsql-export-utilities)
- [PLEX project page on GitHub](https://github.com/ogobrecht/plex)
@ -29,7 +30,8 @@ DEPENDENCIES
The package itself is independend, but functionality varies on the following conditions:
- For APEX app export: APEX >= 5.1.4 installed
- NOT YET IMPLEMENTED: For ORDS REST service export: ORDS >= FIXME installed
- For ORDS modules export: ORDS >= 18.3 installed (I think package ords_export is included since this version, but I don't know it)
- ATTENTION: There seems to be a bug in ORDS 19.2 which prevents you to export ORDS modules via the package ords_export: https://community.oracle.com/thread/4292776; please see plex_error_log.md, if you miss your ORDS modules after an export - this is no problem of PLEX
INSTALLATION
@ -43,6 +45,16 @@ INSTALLATION
CHANGELOG
- 2.1.0 (2019-12-30)
- Function BackApp:
- New parameter to include ORDS modules (p_include_ords_modules)
- New parameter to remove the outer column list on views, which is added by the compiler (p_object_view_remove_col_list); this was done in the past implicitly and can now be switched off; thanks to twitter.com/JKaschuba for the hint
- Object DDL: Comments for tables and views are now included
- Script templates: Improved export speed by using a base64 encoded zip file instead of a global temporary table to unload the files
- Fixed: Unable to export JAVA objects on systems with 30 character object names; thanks to twitter.com/JKaschuba for the hint
- Fixed: Views appears two times in resulting collection, each double file is postfixed with "_2" and empty
- Fixed: Tables and indices of materialized view definitions are exported (should be hidden)
- New function to_base64: convert BLOB into base64 encoded CLOB - this is helpful to download a BLOB file (like a zip file) with SQL*Plus
- 2.0.2 (2019-08-16)
- Fixed: Function BackApp throws error on large APEX UI install files (ORA-06502: PL/SQL: numeric or value error: character string buffer too small)
- 2.0.1 (2019-07-09)
@ -50,35 +62,36 @@ CHANGELOG
- 2.0.0 (2019-06-20)
- Package is now independend from APEX to be able to export schema object DDL and table data without an APEX installation
- ATTENTION: The return type of functions BackApp and Queries_to_CSV has changed from `apex_t_export_files` to `plex.tab_export_files`
- New parameters to filter for object types
- New parameters to change base paths for backend, frontend and data
- Function BackApp:
- New parameters to filter for object types
- New parameters to change base paths for backend, frontend and data
- 1.2.1 (2019-03-13)
- Fix script templates: Change old parameters in plex.backapp call
- Fixed: Script templates for function BackApp used old/invalid parameters
- Add install and uninstall scripts for PLEX itself
- 1.2.0 (2018-10-31)
- New: All like/not like parameters are now translated internally with the escape character set to backslash like so `... like 'YourExpression' escape '\'`
- Fixed: Binary data type columns (raw, long_raw, blob, bfile) should no longer break the export data to CSV functionality
- Function BackApp: All like/not like parameters are now translated internally with the escape character set to backslash like so `... like 'YourExpression' escape '\'`
- Function Queries_to_CSV: Binary data type columns (raw, long_raw, blob, bfile) should no longer break the export
- 1.1.0 (2018-09-23)
- Change filter parameter from regular expression to list of like expressions for easier handling
- Function BackApp: Change filter parameter from regular expression to list of like expressions for easier handling
- 1.0.0 (2018-08-26)
- First public release
SIGNATURE
```sql
- First public release
SIGNATURE
```sql
PACKAGE PLEX AUTHID current_user IS
c_plex_name CONSTANT VARCHAR2(30 CHAR) := 'PLEX - PL/SQL Export Utilities';
c_plex_version CONSTANT VARCHAR2(10 CHAR) := '2.0.2';
c_plex_version CONSTANT VARCHAR2(10 CHAR) := '2.1.0';
c_plex_url CONSTANT VARCHAR2(40 CHAR) := 'https://github.com/ogobrecht/plex';
c_plex_license CONSTANT VARCHAR2(10 CHAR) := 'MIT';
c_plex_license_url CONSTANT VARCHAR2(60 CHAR) := 'https://github.com/ogobrecht/plex/blob/master/LICENSE.txt';
c_plex_author CONSTANT VARCHAR2(20 CHAR) := 'Ottmar Gobrecht';
```
<h2><a id="backapp"></a>Function backapp</h2>
<!------------------------------------------>
c_plex_author CONSTANT VARCHAR2(20 CHAR) := 'Ottmar Gobrecht';
```
<h2><a id="backapp"></a>Function backapp</h2>
<!------------------------------------------>
Get a file collection of an APEX application (or the current user/schema only) including:
- The app export SQL files splitted ready to use for version control and deployment
@ -93,9 +106,11 @@ DECLARE
l_file_collection plex.tab_export_files;
BEGIN
l_file_collection := plex.backapp(
p_app_id => 100, -- parameter only available when APEX installed
p_include_object_ddl => false,
p_include_data => false);
p_app_id => 100, -- parameter only available when APEX is installed
p_include_ords_modules => true, -- parameter only available when ORDS is installed
p_include_object_ddl => false,
p_include_data => false,
p_include_templates => false);
-- do something with the file collection
FOR i IN 1..l_file_collection.count LOOP
@ -114,9 +129,11 @@ DECLARE
l_zip_file BLOB;
BEGIN
l_zip_file := plex.to_zip(plex.backapp(
p_app_id => 100, -- parameter only available when APEX installed
p_include_object_ddl => true,
p_include_data => false));
p_app_id => 100, -- parameter only available when APEX is installed
p_include_ords_modules => true, -- parameter only available when ORDS is installed
p_include_object_ddl => true,
p_include_data => false,
p_include_templates => true));
-- do something with the zip file
-- Your code here...
END;
@ -132,90 +149,96 @@ WITH
FUNCTION backapp RETURN BLOB IS
BEGIN
RETURN plex.to_zip(plex.backapp(
-- All parameters are optional and shown with their defaults
-- App related options (only available, when APEX is installed):
p_app_id => NULL,
p_app_date => true,
p_app_public_reports => true,
p_app_private_reports => false,
p_app_notifications => false,
p_app_translations => true,
p_app_pkg_app_mapping => false,
p_app_original_ids => false,
p_app_subscriptions => true,
p_app_comments => true,
p_app_supporting_objects => NULL,
p_app_include_single_file => false,
p_app_build_status_run_only => false,
-- Object related options:
p_include_object_ddl => false,
p_object_type_like => NULL,
p_object_type_not_like => NULL,
p_object_name_like => NULL,
p_object_name_not_like => NULL,
-- Data related options:
p_include_data => false,
p_data_as_of_minutes_ago => 0,
p_data_max_rows => 1000,
p_data_table_name_like => NULL,
p_data_table_name_not_like => NULL,
-- Miscellaneous options:
p_include_templates => true,
p_include_runtime_log => true,
p_include_error_log => true,
p_base_path_backend => 'app_backend',
p_base_path_frontend => 'app_frontend',
p_base_path_data => 'app_data'));
p_app_id => 100, -- parameter only available when APEX is installed
p_include_ords_modules => true, -- parameter only available when ORDS is installed
p_include_object_ddl => true,
p_include_data => false,
p_include_templates => true));
END backapp;
SELECT backapp FROM dual;
```
SIGNATURE
EXAMPLE ZIP FILE SQL*Plus
```sql
-- SQL*Plus can only handle CLOBs, no BLOBs - so we are forced to create a CLOB
-- for spooling the content to the client disk. You need to decode the base64
-- encoded file before you are able to unzip the content. Also see this blog
-- post how to do this on the different operating systems:
-- https://www.igorkromin.net/index.php/2017/04/26/base64-encode-or-decode-on-the-command-line-without-installing-extra-tools-on-linux-windows-or-macos/
-- Example Windows: certutil -decode app_100.zip.base64 app_100.zip
-- Example Mac: base64 -D -i app_100.zip.base64 -o app_100.zip
-- Example Linux: base64 -d app_100.zip.base64 > app_100.zip
set verify off feedback off heading off termout off
set trimout on trimspool on pagesize 0 linesize 5000 long 100000000 longchunksize 32767
whenever sqlerror exit sql.sqlcode rollback
variable contents clob
BEGIN
:contents := plex.to_base64(plex.to_zip(plex.backapp(
p_app_id => 100, -- parameter only available when APEX is installed
p_include_ords_modules => true, -- parameter only available when ORDS is installed
p_include_object_ddl => true,
p_include_data => false,
p_include_templates => true)));
END;
/
spool "app_100.zip.base64"
print contents
spool off
```
SIGNATURE
```sql
FUNCTION backapp (
$if $$apex_installed $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.
p_app_public_reports IN BOOLEAN DEFAULT true, -- If true, include public reports that a user saved.
p_app_private_reports IN BOOLEAN DEFAULT false, -- If true, include private reports that a user saved.
p_app_notifications IN BOOLEAN DEFAULT false, -- If true, include report notifications.
p_app_translations IN BOOLEAN DEFAULT true, -- If true, include application translation mappings and all text from the translation repository.
p_app_pkg_app_mapping IN BOOLEAN DEFAULT false, -- If true, export installed packaged applications with references to the packaged application definition. If FALSE, export them as normal applications.
p_app_original_ids IN BOOLEAN DEFAULT false, -- If true, export with the IDs as they were when the application was imported.
p_app_subscriptions IN BOOLEAN DEFAULT true, -- If true, components contain subscription references.
p_app_comments IN BOOLEAN DEFAULT true, -- If true, include developer comments.
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.
-- APEX App:
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.
p_app_public_reports IN BOOLEAN DEFAULT true, -- If true, include public reports that a user saved.
p_app_private_reports IN BOOLEAN DEFAULT false, -- If true, include private reports that a user saved.
p_app_notifications IN BOOLEAN DEFAULT false, -- If true, include report notifications.
p_app_translations IN BOOLEAN DEFAULT true, -- If true, include application translation mappings and all text from the translation repository.
p_app_pkg_app_mapping IN BOOLEAN DEFAULT false, -- If true, export installed packaged applications with references to the packaged application definition. If FALSE, export them as normal applications.
p_app_original_ids IN BOOLEAN DEFAULT false, -- If true, export with the IDs as they were when the application was imported.
p_app_subscriptions IN BOOLEAN DEFAULT true, -- If true, components contain subscription references.
p_app_comments IN BOOLEAN DEFAULT true, -- If true, include developer comments.
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_type_like IN VARCHAR2 DEFAULT null, -- A comma separated list of like expressions to filter the objects - example: '%BODY,JAVA%' will be translated to: ... from user_objects where ... and (object_type like '%BODY' escape '\' or object_type like 'JAVA%' escape '\').
p_object_type_not_like IN VARCHAR2 DEFAULT null, -- A comma separated list of not like expressions to filter the objects - example: '%BODY,JAVA%' will be translated to: ... from user_objects where ... and (object_type not like '%BODY' escape '\' and object_type not like 'JAVA%' escape '\').
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: ... from user_objects where ... and (object_name like 'EMP%' escape '\' or object_name like 'DEPT%' escape '\').
p_object_name_not_like IN VARCHAR2 DEFAULT null, -- A comma separated list of not like expressions to filter the objects - example: 'EMP%,DEPT%' will be translated to: ... from user_objects where ... and (object_name not like 'EMP%' escape '\' and object_name not like 'DEPT%' escape '\').
-- Data related options:
p_include_data IN BOOLEAN DEFAULT false, -- If true, include CSV data of each table.
p_data_as_of_minutes_ago IN NUMBER DEFAULT 0, -- Read consistent data with the resulting timestamp(SCN).
p_data_max_rows IN NUMBER DEFAULT 1000, -- Maximum number of rows per table.
p_data_table_name_like IN VARCHAR2 DEFAULT null, -- A comma separated list of like expressions to filter the tables - example: 'EMP%,DEPT%' will be translated to: where ... and (table_name like 'EMP%' escape '\' or table_name like 'DEPT%' escape '\').
p_data_table_name_not_like IN VARCHAR2 DEFAULT null, -- A comma separated list of not like expressions to filter the tables - example: 'EMP%,DEPT%' will be translated to: where ... and (table_name not like 'EMP%' escape '\' and table_name not like 'DEPT%' escape '\').
-- Miscellaneous options:
p_include_templates IN BOOLEAN DEFAULT true, -- If true, include templates for README.md, export and install scripts.
p_include_runtime_log IN BOOLEAN DEFAULT true, -- If true, generate file plex_runtime_log.md with detailed runtime infos.
p_include_error_log IN BOOLEAN DEFAULT true, -- If true, generate file plex_error_log.md with detailed error messages.
p_base_path_backend IN VARCHAR2 DEFAULT 'app_backend', -- The base path in the project root for the database DDL files.
p_base_path_frontend IN VARCHAR2 DEFAULT 'app_frontend', -- The base path in the project root for the APEX UI install files.
p_base_path_data IN VARCHAR2 DEFAULT 'app_data') -- The base path in the project root for the data files.
RETURN tab_export_files;
```
<h2><a id="add_query"></a>Procedure add_query</h2>
<!----------------------------------------------->
$if $$ords_installed $then
-- ORDS Modules:
p_include_ords_modules IN BOOLEAN DEFAULT false, -- If true, include ORDS modules of current user/schema.
$end
-- Schema Objects:
p_include_object_ddl IN BOOLEAN DEFAULT false, -- If true, include DDL of current user/schema and all its objects.
p_object_type_like IN VARCHAR2 DEFAULT null, -- A comma separated list of like expressions to filter the objects - example: '%BODY,JAVA%' will be translated to: ... from user_objects where ... and (object_type like '%BODY' escape '\' or object_type like 'JAVA%' escape '\').
p_object_type_not_like IN VARCHAR2 DEFAULT null, -- A comma separated list of not like expressions to filter the objects - example: '%BODY,JAVA%' will be translated to: ... from user_objects where ... and (object_type not like '%BODY' escape '\' and object_type not like 'JAVA%' escape '\').
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: ... from user_objects where ... and (object_name like 'EMP%' escape '\' or object_name like 'DEPT%' escape '\').
p_object_name_not_like IN VARCHAR2 DEFAULT null, -- A comma separated list of not like expressions to filter the objects - example: 'EMP%,DEPT%' will be translated to: ... from user_objects where ... and (object_name not like 'EMP%' escape '\' and object_name not like 'DEPT%' escape '\').
p_object_view_remove_col_list IN BOOLEAN DEFAULT true, -- If true, the outer column list, added by Oracle on views during compilation, is removed
-- Table Data:
p_include_data IN BOOLEAN DEFAULT false, -- If true, include CSV data of each table.
p_data_as_of_minutes_ago IN NUMBER DEFAULT 0, -- Read consistent data with the resulting timestamp(SCN).
p_data_max_rows IN NUMBER DEFAULT 1000, -- Maximum number of rows per table.
p_data_table_name_like IN VARCHAR2 DEFAULT null, -- A comma separated list of like expressions to filter the tables - example: 'EMP%,DEPT%' will be translated to: where ... and (table_name like 'EMP%' escape '\' or table_name like 'DEPT%' escape '\').
p_data_table_name_not_like IN VARCHAR2 DEFAULT null, -- A comma separated list of not like expressions to filter the tables - example: 'EMP%,DEPT%' will be translated to: where ... and (table_name not like 'EMP%' escape '\' and table_name not like 'DEPT%' escape '\').
-- General Options:
p_include_templates IN BOOLEAN DEFAULT true, -- If true, include templates for README.md, export and install scripts.
p_include_runtime_log IN BOOLEAN DEFAULT true, -- If true, generate file plex_runtime_log.md with detailed runtime infos.
p_include_error_log IN BOOLEAN DEFAULT true, -- If true, generate file plex_error_log.md with detailed error messages.
p_base_path_backend IN VARCHAR2 DEFAULT 'app_backend', -- The base path in the project root for the Schema objects.
p_base_path_frontend IN VARCHAR2 DEFAULT 'app_frontend', -- The base path in the project root for the APEX app.
p_base_path_web_services IN VARCHAR2 DEFAULT 'app_web_services', -- The base path in the project root for the ORDS modules.
p_base_path_data IN VARCHAR2 DEFAULT 'app_data') -- The base path in the project root for the table data.
RETURN tab_export_files;
```
<h2><a id="add_query"></a>Procedure add_query</h2>
<!----------------------------------------------->
Add a query to be processed by the method queries_to_csv. You can add as many queries as you like.
EXAMPLE
@ -227,21 +250,21 @@ BEGIN
p_file_name => 'user_tables');
END;
/
```
SIGNATURE
```sql
```
SIGNATURE
```sql
PROCEDURE add_query (
p_query IN VARCHAR2, -- The query itself
p_file_name IN VARCHAR2, -- File name like 'Path/to/your/file-without-extension'.
p_max_rows IN NUMBER DEFAULT 1000); -- The maximum number of rows to be included in your file.
```
<h2><a id="queries_to_csv"></a>Function queries_to_csv</h2>
<!-------------------------------------------------------->
p_max_rows IN NUMBER DEFAULT 1000); -- The maximum number of rows to be included in your file.
```
<h2><a id="queries_to_csv"></a>Function queries_to_csv</h2>
<!-------------------------------------------------------->
Export one or more queries as CSV data within a file collection.
EXAMPLE BASIC USAGE
@ -270,7 +293,7 @@ END;
/
```
EXPORT EXPORT ZIP FILE PL/SQL
EXAMPLE EXPORT ZIP FILE PL/SQL
```sql
DECLARE
@ -312,22 +335,55 @@ WITH
SELECT queries_to_csv_zip FROM dual;
```
SIGNATURE
EXAMPLE ZIP FILE SQL*Plus
```sql
-- SQL*Plus can only handle CLOBs, no BLOBs - so we are forced to create a CLOB
-- for spooling the content to the client disk. You need to decode the base64
-- encoded file before you are able to unzip the content. Also see this blog
-- post how to do this on the different operating systems:
-- https://www.igorkromin.net/index.php/2017/04/26/base64-encode-or-decode-on-the-command-line-without-installing-extra-tools-on-linux-windows-or-macos/
-- Example Windows: certutil -decode metadata.zip.base64 metadata.zip
-- Example Mac: base64 -D -i metadata.zip.base64 -o metadata.zip
-- Example Linux: base64 -d metadata.zip.base64 > metadata.zip
set verify off feedback off heading off termout off
set trimout on trimspool on pagesize 0 linesize 5000 long 100000000 longchunksize 32767
whenever sqlerror exit sql.sqlcode rollback
variable contents clob
BEGIN
--fill the queries array
plex.add_query(
p_query => 'select * from user_tables',
p_file_name => 'user_tables');
plex.add_query(
p_query => 'select * from user_tab_columns',
p_file_name => 'user_tab_columns',
p_max_rows => 10000);
-- process the queries
:contents := plex.to_base64(plex.to_zip(plex.queries_to_csv));
END;
/
spool "metadata.zip.base64"
print contents
spool off
```
SIGNATURE
```sql
FUNCTION queries_to_csv (
p_delimiter IN VARCHAR2 DEFAULT ',', -- The column delimiter.
p_quote_mark IN VARCHAR2 DEFAULT '"', -- Used when the data contains the delimiter character.
p_header_prefix IN VARCHAR2 DEFAULT NULL, -- Prefix the header line with this text.
p_include_runtime_log IN BOOLEAN DEFAULT true, -- If true, generate file plex_runtime_log.md with runtime statistics.
p_include_error_log IN BOOLEAN DEFAULT true) -- If true, generate file plex_error_log.md with detailed error messages.
RETURN tab_export_files;
```
<h2><a id="to_zip"></a>Function to_zip</h2>
<!---------------------------------------->
RETURN tab_export_files;
```
<h2><a id="to_zip"></a>Function to_zip</h2>
<!---------------------------------------->
Convert a file collection to a zip file.
EXAMPLE
@ -341,50 +397,75 @@ BEGIN
p_include_object_ddl => true));
-- do something with the zip file...
END;
```
SIGNATURE
```sql
```
SIGNATURE
```sql
FUNCTION to_zip (
p_file_collection IN tab_export_files) -- The file collection to zip.
RETURN BLOB;
```
<h2><a id="view_error_log"></a>Function view_error_log</h2>
<!-------------------------------------------------------->
RETURN BLOB;
```
<h2><a id="to_base64"></a>Function to_base64</h2>
<!---------------------------------------------->
Encodes a BLOB into a Base64 CLOB for transfers over a network (like with SQL*Plus). For encoding on the client side see [this blog article](https://www.igorkromin.net/index.php/2017/04/26/base64-encode-or-decode-on-the-command-line-without-installing-extra-tools-on-linux-windows-or-macos/).
```sql
DECLARE
l_clob CLOB;
BEGIN
l_clob := plex.to_base64(plex.to_zip(plex.backapp(
p_app_id => 100,
p_include_object_ddl => true)));
-- do something with the clob...
END;
```
SIGNATURE
```sql
FUNCTION to_base64(
p_blob IN BLOB) -- The BLOB to convert.
RETURN CLOB;
```
<h2><a id="view_error_log"></a>Function view_error_log</h2>
<!-------------------------------------------------------->
View the error log from the last plex run. The internal array for the error log is cleared on each call of BackApp or Queries_to_CSV.
EXAMPLE
```sql
SELECT * FROM TABLE(plex.view_error_log);
```
SIGNATURE
```sql
FUNCTION view_error_log RETURN tab_error_log PIPELINED;
```
<h2><a id="view_runtime_log"></a>Function view_runtime_log</h2>
<!------------------------------------------------------------>
```
SIGNATURE
```sql
FUNCTION view_error_log RETURN tab_error_log PIPELINED;
```
<h2><a id="view_runtime_log"></a>Function view_runtime_log</h2>
<!------------------------------------------------------------>
View the runtime log from the last plex run. The internal array for the runtime log is cleared on each call of BackApp or Queries_to_CSV.
EXAMPLE
```sql
SELECT * FROM TABLE(plex.view_runtime_log);
```
SIGNATURE
```sql
FUNCTION view_runtime_log RETURN tab_runtime_log PIPELINED;
```
```
SIGNATURE
```sql
FUNCTION view_runtime_log RETURN tab_runtime_log PIPELINED;
```

82
package-lock.json generated
View File

@ -542,7 +542,8 @@
},
"ansi-regex": {
"version": "2.1.1",
"bundled": true
"bundled": true,
"optional": true
},
"aproba": {
"version": "1.2.0",
@ -560,11 +561,13 @@
},
"balanced-match": {
"version": "1.0.0",
"bundled": true
"bundled": true,
"optional": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
"optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@ -577,15 +580,18 @@
},
"code-point-at": {
"version": "1.1.0",
"bundled": true
"bundled": true,
"optional": true
},
"concat-map": {
"version": "0.0.1",
"bundled": true
"bundled": true,
"optional": true
},
"console-control-strings": {
"version": "1.1.0",
"bundled": true
"bundled": true,
"optional": true
},
"core-util-is": {
"version": "1.0.2",
@ -688,7 +694,8 @@
},
"inherits": {
"version": "2.0.3",
"bundled": true
"bundled": true,
"optional": true
},
"ini": {
"version": "1.3.5",
@ -698,6 +705,7 @@
"is-fullwidth-code-point": {
"version": "1.0.0",
"bundled": true,
"optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@ -710,17 +718,20 @@
"minimatch": {
"version": "3.0.4",
"bundled": true,
"optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
},
"minimist": {
"version": "0.0.8",
"bundled": true
"bundled": true,
"optional": true
},
"minipass": {
"version": "2.3.5",
"bundled": true,
"optional": true,
"requires": {
"safe-buffer": "^5.1.2",
"yallist": "^3.0.0"
@ -737,6 +748,7 @@
"mkdirp": {
"version": "0.5.1",
"bundled": true,
"optional": true,
"requires": {
"minimist": "0.0.8"
}
@ -809,7 +821,8 @@
},
"number-is-nan": {
"version": "1.0.1",
"bundled": true
"bundled": true,
"optional": true
},
"object-assign": {
"version": "4.1.1",
@ -819,6 +832,7 @@
"once": {
"version": "1.4.0",
"bundled": true,
"optional": true,
"requires": {
"wrappy": "1"
}
@ -894,7 +908,8 @@
},
"safe-buffer": {
"version": "5.1.2",
"bundled": true
"bundled": true,
"optional": true
},
"safer-buffer": {
"version": "2.1.2",
@ -924,6 +939,7 @@
"string-width": {
"version": "1.0.2",
"bundled": true,
"optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@ -941,6 +957,7 @@
"strip-ansi": {
"version": "3.0.1",
"bundled": true,
"optional": true,
"requires": {
"ansi-regex": "^2.0.0"
}
@ -979,11 +996,13 @@
},
"wrappy": {
"version": "1.0.2",
"bundled": true
"bundled": true,
"optional": true
},
"yallist": {
"version": "3.0.3",
"bundled": true
"bundled": true,
"optional": true
}
}
},
@ -1327,9 +1346,9 @@
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
},
"mixin-deep": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz",
"integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==",
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz",
"integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==",
"requires": {
"for-in": "^1.0.2",
"is-extendable": "^1.0.1"
@ -1640,9 +1659,9 @@
"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
},
"set-value": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz",
"integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==",
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
"integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==",
"requires": {
"extend-shallow": "^2.0.1",
"is-extendable": "^0.1.1",
@ -1893,35 +1912,14 @@
}
},
"union-value": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz",
"integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=",
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz",
"integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==",
"requires": {
"arr-union": "^3.1.0",
"get-value": "^2.0.6",
"is-extendable": "^0.1.1",
"set-value": "^0.4.3"
},
"dependencies": {
"extend-shallow": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
"integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
"requires": {
"is-extendable": "^0.1.0"
}
},
"set-value": {
"version": "0.4.3",
"resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz",
"integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=",
"requires": {
"extend-shallow": "^2.0.1",
"is-extendable": "^0.1.1",
"is-plain-object": "^2.0.1",
"to-object-path": "^0.3.0"
}
}
"set-value": "^2.0.1"
}
},
"unset-value": {

View File

@ -6,8 +6,10 @@
"url": "https://github.com/ogobrecht/plex.git"
},
"scripts": {
"build:docs": "npx ploc --in PLEX.pks --out README.md",
"watch:docs": "chokidar PLEX.pks package.json --initial -c \"npm run build:docs\""
"prebuild": "npx ploc --in src/PLEX.pks --out README.md",
"build": "node src/build.js",
"postbuild": "echo exit | sqlplus -S demo/oracle@localhost:1521/xepdb1 @plex_install.sql",
"watch": "chokidar src/PLEX.pks src/PLEX.pkb src/plex_install.sql --initial -c \"npm run build\""
},
"dependencies": {
"chokidar-cli": "^1.2.2",

File diff suppressed because it is too large Load Diff

4870
PLEX.pkb → src/PLEX.pkb Executable file → Normal file

File diff suppressed because it is too large Load Diff

1075
PLEX.pks → src/PLEX.pks Executable file → Normal file

File diff suppressed because it is too large Load Diff

17
src/build.js Normal file
View File

@ -0,0 +1,17 @@
var fs = require('fs');
var spec =
fs.writeFileSync(
'plex_install.sql',
fs.readFileSync('src/plex_install.sql', 'utf8')
.replace('@plex.pks', function(){return fs.readFileSync('src/plex.pks', 'utf8')})
.replace('@plex.pkb', function(){return fs.readFileSync('src/plex.pkb', 'utf8')})
// Read what this function thing is doing, without it we get wrong results.
// We have dollar signs in our package body text - the last answer explains:
// https://stackoverflow.com/questions/9423722/string-replace-weird-behavior-when-using-dollar-sign-as-replacement
);
fs.copyFileSync(
'src/plex_uninstall.sql',
'plex_uninstall.sql'
);

48
src/plex_install.sql Normal file
View File

@ -0,0 +1,48 @@
set define off feedback off
whenever sqlerror exit sql.sqlcode rollback
prompt
prompt Installing PL/SQL Export Utilities
prompt ==================================
prompt Set compiler flags
DECLARE
v_apex_installed VARCHAR2(5) := 'FALSE'; -- Do not change (is set dynamically).
v_ords_installed VARCHAR2(5) := 'FALSE'; -- Do not change (is set dynamically).
v_utils_public VARCHAR2(5) := 'FALSE'; -- Make utilities public available (for testing or other usages).
v_debug_on VARCHAR2(5) := 'FALSE'; -- Object DDL: extract only one object per type to find problematic ones and save time in big schemas like APEX_XXX.
BEGIN
FOR i IN (SELECT *
FROM all_objects
WHERE object_type = 'SYNONYM'
AND object_name = 'APEX_EXPORT') LOOP
v_apex_installed := 'TRUE';
END LOOP;
FOR i IN (SELECT *
FROM all_objects
WHERE object_type = 'SYNONYM'
AND object_name = 'ORDS_EXPORT') LOOP
v_ords_installed := 'TRUE';
END LOOP;
-- Show unset compiler flags as errors (results for example in errors like "PLW-06003: unknown inquiry directive '$$UTILS_PUBLIC'")
EXECUTE IMMEDIATE 'alter session set plsql_warnings = ''ENABLE:6003''';
-- Finally set compiler flags
EXECUTE IMMEDIATE 'alter session set plsql_ccflags = '''
|| 'apex_installed:' || v_apex_installed || ','
|| 'ords_installed:' || v_ords_installed || ','
|| 'utils_public:' || v_utils_public || ','
|| 'debug_on:' || v_debug_on || '''';
END;
/
prompt Compile package plex (spec)
@plex.pks
show errors
prompt Compile package plex (body)
@plex.pkb
show errors
prompt ==================================
prompt Installation Done
prompt

View File

@ -0,0 +1,57 @@
set define off feedback off
whenever sqlerror exit sql.sqlcode rollback
prompt
prompt Installing PL/SQL Export Utilities
prompt ==================================
prompt Show unset compiler flags as errors (results for example in errors like "PLW-06003: unknown inquiry directive '$$UTILS_PUBLIC'"
alter session set plsql_warnings = 'ENABLE:6003';
prompt ---
prompt Set compiler flags to apex_installed:false, ords_installed:false, utils_public:false, debug_on:false
alter session set plsql_ccflags = 'apex_installed:false, ords_installed:false, utils_public:false, debug_on:false';
prompt Compile package plex (spec)
@plex.pks
show errors
prompt Compile package plex (body)
@plex.pkb
show errors
prompt ---
prompt Set compiler flags: apex_installed:true, ords_installed:false, utils_public:false, debug_on:false
alter session set plsql_ccflags = 'apex_installed:true, ords_installed:false, utils_public:false, debug_on:false';
prompt Compile package plex (spec)
@plex.pks
show errors
prompt Compile package plex (body)
@plex.pkb
show errors
prompt ---
prompt Set compiler flags: apex_installed:false, ords_installed:true, utils_public:false, debug_on:false
alter session set plsql_ccflags = 'apex_installed:false, ords_installed:true, utils_public:false, debug_on:false';
prompt Compile package plex (spec)
@plex.pks
show errors
prompt Compile package plex (body)
@plex.pkb
show errors
prompt ---
prompt Set compiler flags: apex_installed:true, ords_installed:true, utils_public:false, debug_on:false
alter session set plsql_ccflags = 'apex_installed:true, ords_installed:true, utils_public:false, debug_on:false';
prompt Compile package plex (spec)
@plex.pks
show errors
prompt Compile package plex (body)
@plex.pkb
show errors
prompt ==================================
prompt Installation Done
prompt

18
src/plex_test.sql Normal file
View File

@ -0,0 +1,18 @@
-- Inline function because of boolean parameters (needs Oracle 12c or higher).
-- Alternative create a helper function and call that in a SQL context.
WITH
FUNCTION backapp RETURN BLOB IS
BEGIN
RETURN plex.to_zip(plex.backapp(
p_app_id => 100,
p_include_object_ddl => true,
p_include_ords_modules => true,
p_include_data => true,
p_include_templates => true));
END backapp;
SELECT backapp FROM dual;
/
select * from table(plex.view_runtime_log);

30
src/plex_uninstall.sql Normal file
View File

@ -0,0 +1,30 @@
SET DEFINE OFF FEEDBACK OFF
WHENEVER SQLERROR EXIT sql.sqlcode ROLLBACK
prompt
prompt Uninstalling PL/SQL Export Utilities
prompt ====================================
prompt Drop package plex if exists (body)
BEGIN
FOR i IN (SELECT object_type,
object_name
FROM user_objects
WHERE object_type = 'PACKAGE BODY'
AND object_name = 'PLEX') LOOP
EXECUTE IMMEDIATE 'DROP ' || i.object_type || ' ' || i.object_name;
END LOOP;
END;
/
prompt Drop package plex if exists (spec)
BEGIN
FOR i IN (SELECT object_type,
object_name
FROM user_objects
WHERE object_type = 'PACKAGE'
AND object_name = 'PLEX') LOOP
EXECUTE IMMEDIATE 'DROP ' || i.object_type || ' ' || i.object_name;
END LOOP;
END;
/
prompt ====================================
prompt Uninstallation Done
prompt