web_plsql 0.5.1 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/README.md +124 -111
  2. package/examples/server_apex.js +28 -0
  3. package/examples/server_sample.js +30 -0
  4. package/examples/sql/{doc_table.sql → doctable.sql} +1 -1
  5. package/examples/sql/install.sql +6 -9
  6. package/examples/sql/sample_package.sql +27 -0
  7. package/examples/sql/sample_package_body.sql +245 -0
  8. package/examples/static/sample.css +11 -10
  9. package/package.json +90 -83
  10. package/src/cgi.js +127 -0
  11. package/src/error.js +24 -0
  12. package/src/errorPage.js +296 -0
  13. package/src/file.js +77 -0
  14. package/src/handlerLogger.js +21 -0
  15. package/src/handlerMetrics.js +46 -0
  16. package/src/handlerPlSql.js +65 -0
  17. package/src/handlerUpload.js +32 -0
  18. package/src/index.js +17 -0
  19. package/src/oracle.js +80 -0
  20. package/src/parsePage.js +193 -0
  21. package/src/procedure.js +260 -0
  22. package/src/procedureError.js +40 -0
  23. package/src/procedureNamed.js +233 -0
  24. package/src/procedureSanitize.js +215 -0
  25. package/src/procedureVariable.js +57 -0
  26. package/src/request.js +103 -0
  27. package/src/{requestError.ts → requestError.js} +8 -4
  28. package/src/sendResponse.js +104 -0
  29. package/src/server.js +106 -0
  30. package/src/shutdown.js +53 -0
  31. package/src/stream.js +28 -0
  32. package/src/trace.js +74 -0
  33. package/src/tty.js +48 -0
  34. package/src/types.js +146 -0
  35. package/src/upload.js +92 -0
  36. package/src/version.js +23 -0
  37. package/types/cgi.d.ts +4 -0
  38. package/types/error.d.ts +1 -0
  39. package/types/errorPage.d.ts +10 -0
  40. package/types/file.d.ts +5 -0
  41. package/types/handlerLogger.d.ts +2 -0
  42. package/types/handlerMetrics.d.ts +4 -0
  43. package/types/handlerPlSql.d.ts +8 -0
  44. package/types/handlerUpload.d.ts +7 -0
  45. package/types/index.d.ts +10 -0
  46. package/types/oracle.d.ts +5 -0
  47. package/types/parsePage.d.ts +3 -0
  48. package/types/procedure.d.ts +10 -0
  49. package/types/procedureError.d.ts +23 -0
  50. package/types/procedureNamed.d.ts +14 -0
  51. package/types/procedureSanitize.d.ts +14 -0
  52. package/types/procedureVariable.d.ts +9 -0
  53. package/types/request.d.ts +7 -0
  54. package/types/requestError.d.ts +8 -0
  55. package/types/sendResponse.d.ts +4 -0
  56. package/types/server.d.ts +7 -0
  57. package/types/shutdown.d.ts +2 -0
  58. package/types/stream.d.ts +1 -0
  59. package/types/trace.d.ts +5 -0
  60. package/types/tty.d.ts +4 -0
  61. package/types/types.d.ts +251 -0
  62. package/types/upload.d.ts +5 -0
  63. package/types/version.d.ts +7 -0
  64. package/.editorconfig +0 -8
  65. package/.eslintignore +0 -3
  66. package/.eslintrc.js +0 -347
  67. package/CHANGELOG.md +0 -133
  68. package/examples/apex.js +0 -70
  69. package/examples/credentials.js +0 -22
  70. package/examples/oracledb_example.js +0 -30
  71. package/examples/sample.js +0 -101
  72. package/examples/sql/sample.pkb +0 -223
  73. package/examples/sql/sample.pks +0 -24
  74. package/jest.config.js +0 -207
  75. package/src/cgi.ts +0 -95
  76. package/src/config.ts +0 -97
  77. package/src/errorPage.ts +0 -286
  78. package/src/fileUpload.ts +0 -126
  79. package/src/index.ts +0 -65
  80. package/src/page.ts +0 -275
  81. package/src/procedure.ts +0 -360
  82. package/src/procedureError.ts +0 -27
  83. package/src/request.ts +0 -139
  84. package/src/stream.ts +0 -26
  85. package/src/trace.ts +0 -194
  86. package/test/.eslintrc.json +0 -5
  87. package/test/__tests__/cgi.ts +0 -96
  88. package/test/__tests__/config.ts +0 -41
  89. package/test/__tests__/errorPage.ts +0 -101
  90. package/test/__tests__/oracledb_mock.ts +0 -98
  91. package/test/__tests__/server.ts +0 -495
  92. package/test/__tests__/stream.ts +0 -21
  93. package/test/mock/oracledb.ts +0 -85
  94. package/test/static/static.html +0 -1
  95. package/tsconfig.json +0 -24
  96. package/tsconfig.src.json +0 -23
package/README.md CHANGED
@@ -15,141 +15,154 @@ Please feel free to try and suggest any improvements. Your thoughts and ideas ar
15
15
  # Release History
16
16
  See the [changelog](https://github.com/doberkofler/web_plsql/blob/master/CHANGELOG.md).
17
17
 
18
- # Installation
18
+ # Prerequisites
19
+ The connection to the Oracle Database uses the node-oracledb Driver for Oracle Database.
20
+ Please visit the [node-oracledb](https://node-oracledb.readthedocs.io/en/latest/index.html) documentation for more information.
19
21
 
20
- ## Prerequisites
21
- There are several prerequisites needed to both compile and run the Oracle database driver.
22
- Please visit the [node-oracledb INSTALL.md](https://oracle.github.io/node-oracledb/INSTALL.html) page for more information.
23
- On where Oracle is looking for the client consult: https://oracle.github.io/node-oracledb/doc/api.html#oracleclientloading
24
-
25
- ## Installing
22
+ # Installing
26
23
  * Create and move to a new directory
27
- * Create a new npm project (`npm init`)
28
- * Install package (`npm install web_plsql`)
29
- * Install the PL/SQL examples (`sqlplus node_modules/web_plsql/examples/sql/install.sql`)
30
- * Start the sample server (`node node_modules/web_plsql/examples/sample`)
31
- * Invoke a browser and open the page `http://localhost:8000/base`
24
+ * Create a new npm project (`npm i`)
25
+ * Install package (`npm i --omit=dev web_plsql`)
26
+
27
+ # Example
28
+ * Change to the `examples/sql` directory, start SQLPLus, connect to the database as SYS specifying the SYSDBA roleInstall and install the sample schema `@examples/sql/install.sql`.
29
+ * Start the sample server using `node examples/server_sample.js` after having set the ORACLE_SERVER environment variable to the database where you just installed the sample schema.
30
+ * Invoke a browser and open the page `http://localhost/sample`.
31
+
32
+ # Running
33
+ There are 2 main options on how to use the mod_plsql Express middleware:
32
34
 
33
- # Configuration
35
+ ## Make a copy of the `server_sample.js` sample script and configure it accordingly to your needs.
36
+
37
+ The the default server implemented in `src/server.js` and has the following configuration options:
38
+ ```
39
+ /**
40
+ * @typedef {'basic' | 'debug'} errorStyleType
41
+ */
42
+ export const z$errorStyleType = z.enum(['basic', 'debug']);
43
+
44
+ /**
45
+ * @typedef {{alias: string, procedure: string}} pathAliasType
46
+ */
47
+
48
+ /**
49
+ * @typedef {object} configStaticType
50
+ * @property {string} route - The Static route path.
51
+ * @property {string} directoryPath - The Static directory.
52
+ */
53
+
54
+ /**
55
+ * @typedef {object} configPlSqlType
56
+ * @property {string} route - The PL/SQL route path.
57
+ * @property {string} user - The Oracle username.
58
+ * @property {string} password - The Oracle password.
59
+ * @property {string} connectString - The Oracle connect string.
60
+ * @property {string} defaultPage - The default page.
61
+ * @property {pathAliasType} [pathAlias] - The path alias.
62
+ * @property {string} documentTable - The document table.
63
+ */
64
+
65
+ /**
66
+ * @typedef {object} configType
67
+ * @property {number} port - The server port number.
68
+ * @property {configStaticType[]} routeStatic - The static routes.
69
+ * @property {configPlSqlType[]} routePlSql - The PL/SQL routes.
70
+ * @property {errorStyleType} errorStyle - The error style.
71
+ * @property {string} loggerFilename - name of the request logger filename or '' if not required.
72
+ * @property {boolean} monitorConsole - Enable console status monitor.
73
+ */
74
+ ```
34
75
 
35
- ## How does a mod_plsql DAD configuration compare to the web_plsql app
76
+ The following mod_plsql DAD configuration translates to the configuration options as follows:
36
77
 
78
+ **DAD**
37
79
  ```
38
80
  <Location /pls/sample>
39
- SetHandler pls_handler
40
- Order deny,allow
41
- Allow from all
42
- PlsqlDatabaseUsername sample
43
- PlsqlDatabasePassword sample
44
- PlsqlDatabaseConnectString ORCL
45
- PlsqlAuthenticationMode Basic
46
- PlsqlDefaultPage sample.pageindex
47
- PlsqlDocumentTablename doctable
48
- PlsqlErrorStyle DebugStyle
49
- PlsqlNlsLanguage AMERICAN_AMERICA.UTF8
81
+ SetHandler pls_handler
82
+ Order deny,allow
83
+ Allow from all
84
+ PlsqlDatabaseUsername sample
85
+ PlsqlDatabasePassword sample
86
+ PlsqlDatabaseConnectString localhost:1521/ORCL
87
+ PlsqlDefaultPage sample_pkg.pageIndex
88
+ PlsqlDocumentTablename doctable
89
+ PlsqlPathAlias myalias
90
+ PlsqlPathAliasProcedure sample_pkg.page_path_alias
91
+ PlsqlExclusionList sample_pkg.page_exclusion_list
92
+ PlsqlRequestValidationFunction sample_pkg.request_validation_function
93
+ PlsqlErrorStyle DebugStyle
94
+ PlsqlNlsLanguage AMERICAN_AMERICA.UTF8
50
95
  </Location>
51
96
  ```
52
97
 
53
- ```javascript
54
- const fs = require('fs');
55
- const path = require('path');
56
- const express = require('express');
57
- const bodyParser = require('body-parser');
58
- const multipart = require('connect-multiparty');
59
- const cookieParser = require('cookie-parser');
60
- const compression = require('compression');
61
- const morgan = require('morgan');
62
-
63
- const oracledb = require('oracledb');
64
- const webplsql = require('../lib');
65
-
66
- /*
67
- * Allocate the Oracle database pool
68
- */
69
-
70
- const databasePool = oracledb.createPool({
71
- user: 'sample',
72
- password: 'sample',
73
- connectString: 'ORCL',
74
- poolMin: 10,
75
- poolMax: 1000,
76
- poolIncrement: 10,
77
- queueRequests: false,
78
- queueTimeout: 1000
79
- });
80
-
81
- databasePool.catch(e => {
82
- console.error(`Unable to create database pool.\n${e.message}`);
83
- process.exit(1);
84
- });
85
-
86
- /*
87
- * Start the server
88
- */
89
-
90
- const PORT = 8000;
91
- const PATH = '/pls/sample';
92
- const OPTIONS = {
93
- defaultPage: 'sample.pageIndex',
94
- doctable: 'docTable',
95
- errorStyle: 'debug'
96
- };
97
-
98
- // create express app
99
- const app = express();
100
-
101
- // add middleware
102
- app.use(multipart());
103
- app.use(bodyParser.json());
104
- app.use(bodyParser.urlencoded({extended: true}));
105
- app.use(cookieParser());
106
- app.use(compression());
107
- app.use(morgan('combined', {stream: fs.createWriteStream(path.join(process.cwd(), 'access.log'), {flags: 'a'})}));
108
-
109
- // add the oracle pl/sql express middleware
110
- app.use(PATH + '/:name?', webplsql(databasePool, OPTIONS));
111
-
112
- // serving static files
113
- app.use('/static', express.static(path.join(process.cwd(), 'examples/static')));
114
-
115
- // listen on port
116
- console.log(`Waiting on http://localhost:${PORT}${PATH}`);
117
- app.listen(PORT);
98
+ **mod_plsql**
99
+ ```
100
+ {
101
+ port: 80,
102
+ routeStatic: [
103
+ {
104
+ route: '/static',
105
+ directoryPath: 'examples/static',
106
+ },
107
+ ],
108
+ routePlSql: [
109
+ {
110
+ route: '/sample',
111
+ user: 'sample', // PlsqlDatabaseUserName
112
+ password: 'sample', // PlsqlDatabasePassword
113
+ connectString: 'localhost:1521/ORCL', // PlsqlDatabaseConnectString
114
+ defaultPage: 'sample_pkg.page_index', // PlsqlDefaultPage
115
+ documentTable: 'doctable', // PlsqlDocumentTablename
116
+ exclusionList: ['sample_pkg.page_exclusion_list'], // PlsqlExclusionList
117
+ requestValidationFunction: 'sample_pkg.request_validation_function', // PlsqlRequestValidationFunction
118
+ pathAlias: 'myalias', // PlsqlPathAlias
119
+ pathAliasProcedure: 'sample_pkg.page_path_alias', // PlsqlPathAliasProcedure
120
+ errorStyle: 'debug', // PlsqlErrorStyle
121
+ },
122
+ ],
123
+ loggerFilename: 'access.log', // PlsqlLogEnable and PlsqlLogDirectory
124
+ monitorConsole: false,
125
+ }
118
126
  ```
119
127
 
120
- # Missing features
121
-
122
- ## Supported mod_plsql configuration options:
123
- - PlsqlDatabaseConnectString -> specified when creating the oracledb connection pool
124
- - PlsqlDatabaseUserName -> specified when creating the oracledb connection pool
125
- - PlsqlDatabasePassword -> specified when creating the oracledb connection pool
126
- - PlsqlDefaultPage -> use the "doctable" configuration option
127
- - PlsqlDocumentTablename -> use the "defaultPage" configuration option
128
- - PlsqlErrorStyle -> use the "errorStyle" configuration option
129
- - PlsqlLogEnable -> use a HTTP request logger middleware for node.js like morgan
130
- - PlsqlLogDirectory -> use a HTTP request logger middleware for node.js like morgan
131
- - PlsqlPathAlias -> use the "pathAlias.alias" configuration option
132
- - PlsqlPathAliasProcedure -> use the "pathAlias.procedure" configuration option
133
-
134
- ## Features in mod_plsql that are planned t be available in web_plsql:
135
- - PlsqlDocumentPath
136
- - PlsqlDocumentProcedure
137
- - PlsqlExclusionList
138
- - PlsqlRequestValidationFunction
139
- - Support for APEX 5.
128
+ ## Create a custom Express application based on the default server implemented in `src/server.js`.
129
+
130
+ ...
131
+
132
+ # Configuration options
133
+
134
+ ## Supported mod_plsql configuration options
135
+ - PlsqlDatabaseConnectString
136
+ - PlsqlDatabaseUserName
137
+ - PlsqlDatabasePassword
138
+ - PlsqlDefaultPage
139
+ - PlsqlDocumentTablename
140
+ - PlsqlErrorStyle
141
+ - PlsqlLogEnable
142
+ - PlsqlLogDirectory
143
+ - PlsqlPathAlias
144
+ - PlsqlPathAliasProcedure
140
145
  - Default exclusion list.
146
+ - PlsqlRequestValidationFunction
147
+ - PlsqlExclusionList
141
148
  - Basic and custom authentication methods, based on the OWA_SEC package and custom packages.
142
149
 
150
+ ## Features that are planned to be available in web_plsql
151
+ - Support for APEX 5 or greater.
152
+
143
153
  ## Configuration options that will not be supported:
144
- - PlsqlIdleSessionCleanupInterval
154
+ - PlsqlDocumentProcedure
145
155
  - PlsqlAfterProcedure
146
156
  - PlsqlAlwaysDescribeProcedure
147
157
  - PlsqlBeforeProcedure
148
158
  - PlsqlCGIEnvironmentList
159
+ - PlsqlDocumentPath
160
+ - PlsqlIdleSessionCleanupInterval
149
161
  - PlsqlSessionCookieName
150
162
  - PlsqlSessionStateManagement
151
163
  - PlsqlTransferMode
152
164
 
165
+
153
166
  # License
154
167
 
155
168
  [MIT](LICENSE)
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env node
2
+
3
+ import {startServer} from '../src/index.js';
4
+
5
+ void startServer({
6
+ port: 80,
7
+ routeStatic: [
8
+ {
9
+ route: '/i/',
10
+ directoryPath: 'apex/images',
11
+ },
12
+ ],
13
+ routePlSql: [
14
+ {
15
+ route: '/apex',
16
+ user: 'APEX_PUBLIC_USER',
17
+ password: 'secret',
18
+ connectString: process.env.ORACLE_SERVER ?? '',
19
+ defaultPage: 'apex',
20
+ pathAlias: 'r',
21
+ pathAliasProcedure: 'wwv_flow.resolve_friendly_url',
22
+ documentTable: 'wwv_flow_file_objects$',
23
+ errorStyle: 'debug',
24
+ },
25
+ ],
26
+ loggerFilename: 'access.log',
27
+ monitorConsole: false,
28
+ });
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env node
2
+
3
+ import {startServer} from '../src/index.js';
4
+
5
+ void startServer({
6
+ port: 80,
7
+ routeStatic: [
8
+ {
9
+ route: '/static',
10
+ directoryPath: 'examples/static',
11
+ },
12
+ ],
13
+ routePlSql: [
14
+ {
15
+ route: '/sample',
16
+ user: 'sample', // PlsqlDatabaseUserName
17
+ password: 'sample', // PlsqlDatabasePassword
18
+ connectString: process.env.ORACLE_SERVER ?? '', // PlsqlDatabaseConnectString
19
+ defaultPage: 'sample_pkg.page_index', // PlsqlDefaultPage
20
+ documentTable: 'doctable', // PlsqlDocumentTablename
21
+ exclusionList: ['sample_pkg.page_exclusion_list'], // PlsqlExclusionList
22
+ requestValidationFunction: 'sample_pkg.request_validation_function', // PlsqlRequestValidationFunction
23
+ pathAlias: 'myalias', // PlsqlPathAlias
24
+ pathAliasProcedure: 'sample_pkg.page_path_alias', // PlsqlPathAliasProcedure
25
+ errorStyle: 'debug', // PlsqlErrorStyle
26
+ },
27
+ ],
28
+ loggerFilename: 'access.log', // PlsqlLogEnable and PlsqlLogDirectory
29
+ monitorConsole: false,
30
+ });
@@ -2,7 +2,7 @@ DROP TABLE docTable;
2
2
 
3
3
  CREATE TABLE docTable
4
4
  (
5
- NAME VARCHAR(128) UNIQUE NOT NULL,
5
+ NAME VARCHAR(128) PRIMARY KEY,
6
6
  MIME_TYPE VARCHAR(128),
7
7
  DOC_SIZE NUMBER,
8
8
  DAD_CHARSET VARCHAR(128),
@@ -1,3 +1,5 @@
1
+ set echo on termout on
2
+
1
3
  -- set the username
2
4
  define SAMPLE_USER=sample
3
5
 
@@ -12,20 +14,15 @@ GRANT create view TO &&SAMPLE_USER;
12
14
  GRANT create sequence TO &&SAMPLE_USER;
13
15
  GRANT create procedure TO &&SAMPLE_USER;
14
16
  GRANT execute on dbms_lob TO &&SAMPLE_USER;
15
- GRANT execute on dbms_output TO &&SAMPLE_USER;
16
- GRANT execute on dbms_lock TO &&SAMPLE_USER;
17
17
 
18
18
  -- change schema
19
19
  ALTER SESSION SET CURRENT_SCHEMA=&&SAMPLE_USER;
20
20
 
21
21
  -- install document table
22
- @doc_table.sql
22
+ @doctable.sql
23
23
 
24
- -- install demo
25
- @sample.pks
24
+ -- install package
25
+ @sample_package.sql
26
26
  show errors
27
- @sample.pkb
27
+ @sample_package_body.sql
28
28
  show errors
29
-
30
- -- show errors
31
- select * from user_errors;
@@ -0,0 +1,27 @@
1
+ CREATE OR REPLACE
2
+ PACKAGE sample_pkg IS
3
+
4
+ TYPE vc_arr IS TABLE OF VARCHAR2(2000) INDEX BY BINARY_INTEGER;
5
+
6
+ FUNCTION emptyArray RETURN vc_arr;
7
+
8
+ PROCEDURE page_index(p IN VARCHAR2 DEFAULT NULL);
9
+ PROCEDURE pag_simple(text IN VARCHAR2 DEFAULT NULL);
10
+ PROCEDURE page_flexible(name_array IN owa.vc_arr, value_array IN owa.vc_arr);
11
+ PROCEDURE page_array(text IN vc_arr);
12
+ PROCEDURE page_cgi;
13
+ PROCEDURE page_cookie;
14
+ PROCEDURE page_form;
15
+ PROCEDURE page_form_process(firstname IN VARCHAR2 DEFAULT NULL, lastname IN VARCHAR2 DEFAULT NULL, age IN VARCHAR2 DEFAULT NULL, sex IN VARCHAR2 DEFAULT NULL, vehicle IN vc_arr DEFAULT emptyArray);
16
+ PROCEDURE page_file_upload;
17
+ PROCEDURE page_file_uploaded(name_array IN owa.vc_arr, value_array IN owa.vc_arr);
18
+ PROCEDURE page_redirect;
19
+ PROCEDURE page_location;
20
+ PROCEDURE page_other;
21
+ PROCEDURE page_path_alias(p_path IN VARCHAR2);
22
+ PROCEDURE page_exclusion_list;
23
+ PROCEDURE page_request_validation_function;
24
+ FUNCTION request_validation_function(p_proc_name IN VARCHAR2) RETURN BOOLEAN;
25
+
26
+ END sample_pkg;
27
+ /
@@ -0,0 +1,245 @@
1
+ CREATE OR REPLACE
2
+ PACKAGE BODY sample_pkg IS
3
+
4
+ PROCEDURE open_page(title IN VARCHAR2);
5
+ PROCEDURE close_page;
6
+
7
+ FUNCTION emptyArray RETURN vc_arr
8
+ IS
9
+ arr vc_arr;
10
+ BEGIN
11
+ RETURN arr;
12
+ END emptyArray;
13
+
14
+ PROCEDURE page_index(p IN VARCHAR2 DEFAULT NULL)
15
+ IS
16
+ BEGIN
17
+ open_page('web_plsql - Index Page');
18
+ htp.p('<ul>');
19
+ htp.p('<li><a href="sample_pkg.pag_simple?text=some-text">Simple page</a></li>');
20
+ htp.p('<li><a href="sample_pkg.page_array?text=some-text'||CHR(38)||'text=more-text'||CHR(38)||'text=last-text">Array passing</a></li>');
21
+ htp.p('<li><a href="!sample_pkg.page_flexible?p1=v1'||CHR(38)||'p2=v2'||CHR(38)||'p3=v3.1'||CHR(38)||'p3=v3.2"">Flexible parameter passing</a></li>');
22
+ htp.p('<li><a href="sample_pkg.page_cgi">CGI</a></li>');
23
+ htp.p('<li><a href="sample_pkg.page_cookie">Cookies</a></li>');
24
+ htp.p('<li><a href="sample_pkg.page_form">Form</a></li>');
25
+ htp.p('<li><a href="sample_pkg.page_file_upload">File upload</a></li>');
26
+ htp.p('<li><a href="sample_pkg.page_redirect">Redirect</a></li>');
27
+ htp.p('<li><a href="sample_pkg.page_location">Change location</a></li>');
28
+ htp.p('<li><a href="myalias">pathAlias configuration setting</a></li>');
29
+ htp.p('<li><a href="sample_pkg.page_exclusion_list">Custom exclusion list</a></li>');
30
+ htp.p('<li><a href="sample_pkg.page_request_validation_function">Request validation function</a></li>');
31
+ htp.p('</ul>');
32
+ close_page();
33
+ END page_index;
34
+
35
+ PROCEDURE pag_simple(text IN VARCHAR2 DEFAULT NULL)
36
+ IS
37
+ BEGIN
38
+ open_page('web_plsql - Simple page');
39
+ htp.p('<p>'||text||'</p>');
40
+ close_page();
41
+ END pag_simple;
42
+
43
+ PROCEDURE page_array(text IN vc_arr)
44
+ IS
45
+ BEGIN
46
+ open_page('web_plsql - Array parameter passing');
47
+ htp.p('<table>');
48
+ htp.p('<tr><th>value</th></tr>');
49
+ FOR i IN 1 .. text.COUNT LOOP
50
+ htp.p('<tr><td>'||text(i)||'</td></tr>');
51
+ END LOOP;
52
+ htp.p('</table>');
53
+ close_page();
54
+ END page_array;
55
+
56
+ PROCEDURE page_flexible(name_array IN owa.vc_arr, value_array IN owa.vc_arr)
57
+ IS
58
+ BEGIN
59
+ open_page('web_plsql - Flexible parameter passing');
60
+ htp.p('<table>');
61
+ htp.p('<tr><th>name</th><th>value</th></tr>');
62
+ FOR i IN 1 .. name_array.COUNT LOOP
63
+ htp.p('<tr><td>'||name_array(i)||'</td><td>'||value_array(i)||'</td></tr>');
64
+ END LOOP;
65
+ htp.p('</table>');
66
+ close_page();
67
+ END page_flexible;
68
+
69
+ PROCEDURE page_cgi
70
+ IS
71
+ BEGIN
72
+ open_page('web_plsql - CGI');
73
+ htp.p('<table>');
74
+ htp.p('<tr><th>name</th><th>value</th></tr>');
75
+ FOR i IN 1 .. owa.num_cgi_vars LOOP
76
+ htp.p('<tr><td>'||owa.cgi_var_name(i)||'</td><td>'||owa.cgi_var_val(i)||'</td></tr>');
77
+ END LOOP;
78
+ htp.p('</table>');
79
+ close_page();
80
+ END page_cgi;
81
+
82
+ PROCEDURE page_cookie
83
+ IS
84
+ names owa_cookie.vc_arr;
85
+ vals owa_cookie.vc_arr;
86
+ num_vals INTEGER;
87
+ BEGIN
88
+ owa_cookie.get_all(names=>names, vals=>vals, num_vals=>num_vals);
89
+
90
+ owa_util.mime_header('text/html', FALSE);
91
+ owa_cookie.send('demoCookie', TO_CHAR(SYSDATE, 'YYYY.MM.DD HH24:MI:SS'));
92
+ owa_util.http_header_close;
93
+
94
+ open_page('web_plsql - Cookies');
95
+ htp.p('<table>');
96
+ htp.p('<tr><th>name</th><th>value</th></tr>');
97
+ FOR i IN 1 .. num_vals LOOP
98
+ htp.p('<tr><td>'||names(i)||'</td><td>'||vals(i)||'</td></tr>');
99
+ END LOOP;
100
+ htp.p('</table>');
101
+ close_page();
102
+ END page_cookie;
103
+
104
+ PROCEDURE page_form
105
+ IS
106
+ BEGIN
107
+ open_page('web_plsql - Form');
108
+ htp.p('<form method="POST" action="sample_pkg.page_form_process">');
109
+ htp.p('<table>');
110
+ htp.p('<tr><td>First name:</td><td><input type="text" name="firstname"></td></tr>');
111
+ htp.p('<tr><td>Last name:</td><td><input type="text" name="lastname"></td></tr>');
112
+ htp.p('<tr><td>Age:</td><td><input type="text" name="age"></td></tr>');
113
+ htp.p('<tr><td colspan="2"><input type="radio" name="sex" value="male">Male</td></tr>');
114
+ htp.p('<tr><td colspan="2"><input type="radio" name="sex" value="female">Female</td></tr>');
115
+ htp.p('<tr><td colspan="2"><input type="checkbox" name="vehicle" value="Bike">I have a bike</td></tr>');
116
+ htp.p('<tr><td colspan="2"><input type="checkbox" name="vehicle" value="Car">I have a car </td></tr>');
117
+ htp.p('<tr><td colspan="2"><input type="submit" value="Submit"></td></tr>');
118
+ htp.p('</table>');
119
+ htp.p('</form>');
120
+ close_page();
121
+ END page_form;
122
+
123
+ PROCEDURE page_form_process(firstname IN VARCHAR2 DEFAULT NULL, lastname IN VARCHAR2 DEFAULT NULL, age IN VARCHAR2 DEFAULT NULL, sex IN VARCHAR2 DEFAULT NULL, vehicle IN vc_arr DEFAULT emptyArray)
124
+ IS
125
+ PROCEDURE line(name IN VARCHAR2, value IN VARCHAR2)
126
+ IS
127
+ BEGIN
128
+ htp.p('<tr><th>'||name||'</th><td>'||value||'</td></tr>');
129
+ END line;
130
+ BEGIN
131
+ open_page('web_plsql - Form processed');
132
+ htp.p('<table>');
133
+ line('firstname', firstname);
134
+ line('lastname', lastname);
135
+ line('age', age);
136
+ line('sex', sex);
137
+ FOR i IN 1 .. vehicle.COUNT LOOP
138
+ line('vehicle '||i, vehicle(i));
139
+ END LOOP;
140
+ htp.p('</table>');
141
+ close_page();
142
+ END page_form_process;
143
+
144
+ PROCEDURE page_file_upload
145
+ IS
146
+ BEGIN
147
+ open_page('web_plsql - File upload');
148
+ htp.p('<form enctype="multipart/form-data" method="POST" action="!sample_pkg.page_file_uploaded">');
149
+ htp.p('<p>File 1: <input type="file" name="file1" /></p>');
150
+ htp.p('<p>File 2: <input type="file" name="file2" /></p>');
151
+ htp.p('<p>File 3: <input type="file" name="file3" /></p>');
152
+ htp.p('<p><input type="submit" name="submit" value"Upload" /></p>');
153
+ htp.p('</form>');
154
+ close_page();
155
+ END page_file_upload;
156
+
157
+ PROCEDURE page_file_uploaded(name_array IN owa.vc_arr, value_array IN owa.vc_arr)
158
+ IS
159
+ BEGIN
160
+ open_page('web_plsql - File uploaded');
161
+ htp.p('<table>');
162
+ htp.p('<tr><th>name</th><th>value</th></tr>');
163
+ FOR i IN 1 .. name_array.COUNT LOOP
164
+ htp.p('<tr><td>'||name_array(i)||'</td><td>'||value_array(i)||'</td></tr>');
165
+ END LOOP;
166
+ htp.p('</table>');
167
+ close_page();
168
+ END page_file_uploaded;
169
+
170
+ PROCEDURE page_redirect
171
+ IS
172
+ BEGIN
173
+ owa_util.mime_header('text/html', FALSE);
174
+ owa_cookie.send('fromPage', 'sample_pkg.page_redirect');
175
+ owa_util.redirect_url(curl=>'sample_pkg.page_other', bclose_header=>FALSE);
176
+ owa_util.http_header_close;
177
+ END page_redirect;
178
+
179
+ PROCEDURE page_location
180
+ IS
181
+ BEGIN
182
+ open_page('web_plsql - page_location');
183
+ htp.p('<script>self.top.location.replace("sample_pkg.page_other");</script>');
184
+ close_page();
185
+ END page_location;
186
+
187
+ PROCEDURE page_other
188
+ IS
189
+ BEGIN
190
+ open_page('web_plsql - Other page');
191
+ close_page();
192
+ END page_other;
193
+
194
+ PROCEDURE page_path_alias(p_path IN VARCHAR2)
195
+ IS
196
+ BEGIN
197
+ open_page('web_plsql - pathAlias page');
198
+ htp.p('<p>p_path: "'||p_path||'"</p>');
199
+ close_page();
200
+ END page_path_alias;
201
+
202
+ PROCEDURE page_exclusion_list
203
+ IS
204
+ BEGIN
205
+ open_page('web_plsql - page_exclusion_list');
206
+ close_page();
207
+ END page_exclusion_list;
208
+
209
+ PROCEDURE page_request_validation_function
210
+ IS
211
+ BEGIN
212
+ open_page('web_plsql - page_request_validation_function');
213
+ close_page();
214
+ END page_request_validation_function;
215
+
216
+ FUNCTION request_validation_function(p_proc_name IN VARCHAR2) RETURN BOOLEAN
217
+ IS
218
+ BEGIN
219
+ RETURN LOWER(p_proc_name) != 'sample_pkg.page_request_validation_function';
220
+ END request_validation_function;
221
+
222
+ PROCEDURE open_page(title IN VARCHAR2)
223
+ IS
224
+ BEGIN
225
+ htp.p('<!DOCTYPE html>');
226
+ htp.p('<html>');
227
+ htp.p('<head>');
228
+ htp.p('<title>'||title||'</title>');
229
+ htp.p('<meta charset="utf-8">');
230
+ htp.p('<link rel="stylesheet" type="text/css" href="/static/sample.css" />');
231
+ htp.p('</head>');
232
+ htp.p('<body>');
233
+ htp.p('<h1>'||title||'</h1>');
234
+ htp.p('<p><a href="sample_pkg.page_index">Menu</a></p>');
235
+ END open_page;
236
+
237
+ PROCEDURE close_page
238
+ IS
239
+ BEGIN
240
+ htp.p('</body>');
241
+ htp.p('</html>');
242
+ END close_page;
243
+
244
+ END sample_pkg;
245
+ /
@@ -3,23 +3,24 @@ body {
3
3
  }
4
4
 
5
5
  table {
6
- color: #333;
7
- width: 640px;
8
- border-collapse:
9
- collapse; border-spacing: 0;
6
+ color: #333;
7
+ width: 640px;
8
+ border-collapse: collapse;
9
+ border-spacing: 0;
10
10
  }
11
11
 
12
- td, th {
13
- border: 1px solid #CCC;
12
+ td,
13
+ th {
14
+ border: 1px solid #ccc;
14
15
  height: 30px;
15
16
  }
16
17
 
17
18
  th {
18
- background: #F3F3F3;
19
- font-weight: bold;
19
+ background: #f3f3f3;
20
+ font-weight: bold;
20
21
  }
21
22
 
22
23
  td {
23
- background: #FAFAFA;
24
- text-align: center;
24
+ background: #fafafa;
25
+ text-align: center;
25
26
  }