From 08f61d36c134069ca67e75f492a458b48f99a000 Mon Sep 17 00:00:00 2001
From: Nirmala Sundarappa
Date: Mon, 24 Jul 2017 09:25:44 -0700
Subject: [PATCH 01/92] Checking in servlets for UCP
---
java/ucp/WebLogicServer_Servlet/Readme.md | 35 ++++++++++++++++
java/ucp/WebLogicServer_Servlet/build.xml | 51 +++++++++++++++++++++++
2 files changed, 86 insertions(+)
create mode 100644 java/ucp/WebLogicServer_Servlet/Readme.md
create mode 100644 java/ucp/WebLogicServer_Servlet/build.xml
diff --git a/java/ucp/WebLogicServer_Servlet/Readme.md b/java/ucp/WebLogicServer_Servlet/Readme.md
new file mode 100644
index 00000000..ef28555b
--- /dev/null
+++ b/java/ucp/WebLogicServer_Servlet/Readme.md
@@ -0,0 +1,35 @@
+# WebLogicServer Java Servlet
+The Oracle JDBC drivers allow Java applications to connect and process data in the Oracle Database. Oracle WebLogic Server is the application server for building and deploying enterprise Java EE applications. This repository has code samples for a Java Servlet that connects to the Oracle Database using the Oracle JDBC driver. We have furnished `build.xml` to compile the servlet and the `Readme.md` that has instructions to compile and deploy this servlet on WebLogic Server. If you have subscribed to any Oracle Database Service on Cloud such as DBCS, EECS, BMCS etc., follow these instructions to verify the connectivity with WebLogic Server.
+
+# What you need to install?
+
+* **Web Logic Server v12.2.1.2**: Download and install the [WebLogic Server v12.2.1.2](http://www.oracle.com/technetwork/middleware/weblogic/downloads/index.html)
+* **Apache Ant**: Make sure you have [Apache ANT](http://ant.apache.org/) to compile the source code
+* **JDBC driver**: You can choose to use the JDBC driver (ojdbc7.jar) that is shipped with WebLogicServer v 12.2.1.2 or you can download and use the latest [ojdbc8.jar from OTN](http://www.oracle.com/technetwork/database/features/jdbc/jdbc-ucp-122-3110062.html)
+* **Oracle Database**: You need to have a working Oracle Database with the credentials to verify the successful connection. Make sure either you have subscribed to Oracle Database Service on Cloud (DBCS, EECS, BMCS, ExaCS) or installed an Oracle Database on premise.
+
+# Steps to compile the Java Servlet
+
+* **Update build.xml**: Download the `build.xml` present in this repository. Update WLS_HOME to point to the location where WebLogic Server is installed.
+* **Create a Datasource in WebLogicServer**: Create an Oracle Datasource through the admin console. Refer to the blog for more details ["Create and Deploy a Java Servlet using WebLogic Server"](https://blogs.oracle.com/dev2dev/create-and-deploy-a-java-servlet-using-weblogic-server-wls). Let us name this datasource as `orcljdbc_ds`
+* **Update JDBCSample_Servlet**: Download the `JDBCSample_Servlet` from this repository and Update the method `getDataSource()` to use the correct Oracle datasource name. E.g.,`orcljdbc_ds` created through admin console.
+* **Create the war file**: Go to the location where the `build.xml` is located. Execute the command `ant` that will compile and also create the `JDBCSample.war` file in the `dist` folder.
+
+# Steps to deploy and run the Java Servlet
+
+* **Deploy the WAR file**: Start the WebLogic Server and open the admin console. Follow the steps in this [blog](https://blogs.oracle.com/dev2dev/create-and-deploy-a-java-servlet-using-weblogic-server-wls#step8) to deploy `JDBCSample.war`
+* **Invoke the Servlet**: Invoke the servlet at `https://localhost:7001/JDBCSample/JDBCSample_Servlet`
+* **Check the Results**: Check the results on the page and make sure that it prints driver information retrieved from the Oracle database.
+
+# Other Resources
+
+* [Create and Deploy a Java Servlet using WebLogic Server](https://blogs.oracle.com/dev2dev/create-and-deploy-a-java-servlet-using-weblogic-server-wls)
+* [How to use the latest ojdbc8.jar in WebLogic Server?](http://www.oracle.com/technetwork/database/application-development/jdbc/jdbc-eecontainers-cloud.html#wls)
+* [Using Java Containers with Exadata Express Cloud Service (EECS)](http://www.oracle.com/technetwork/database/application-development/jdbc/jdbc-eecontainers-cloud.html#wls)
+
+
+
+
+
+
+
diff --git a/java/ucp/WebLogicServer_Servlet/build.xml b/java/ucp/WebLogicServer_Servlet/build.xml
new file mode 100644
index 00000000..f3d63b3d
--- /dev/null
+++ b/java/ucp/WebLogicServer_Servlet/build.xml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
From 93d6c5d39fc05f101dfc17ff7edf9142c95be09f Mon Sep 17 00:00:00 2001
From: Kuassi Mensah
Date: Tue, 10 Apr 2018 11:07:43 -0700
Subject: [PATCH 02/92] Added code samples under test/
---
.../oracle/adbaoverjdbc/test/FirstLight.java | 267 ++++++++++++++++++
1 file changed, 267 insertions(+)
create mode 100644 java/AoJ/test/com/oracle/adbaoverjdbc/test/FirstLight.java
diff --git a/java/AoJ/test/com/oracle/adbaoverjdbc/test/FirstLight.java b/java/AoJ/test/com/oracle/adbaoverjdbc/test/FirstLight.java
new file mode 100644
index 00000000..859c98b2
--- /dev/null
+++ b/java/AoJ/test/com/oracle/adbaoverjdbc/test/FirstLight.java
@@ -0,0 +1,267 @@
+/*
+ * Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.oracle.adbaoverjdbc.test;
+
+import jdk.incubator.sql2.AdbaType;
+import jdk.incubator.sql2.Connection;
+import jdk.incubator.sql2.DataSourceFactory;
+import jdk.incubator.sql2.DataSource;
+import jdk.incubator.sql2.Result;
+import jdk.incubator.sql2.SqlException;
+import jdk.incubator.sql2.Transaction;
+import java.util.Properties;
+import java.util.concurrent.CompletionStage;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collector;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+import static com.oracle.adbaoverjdbc.JdbcConnectionProperties.JDBC_CONNECTION_PROPERTIES;
+
+/**
+ * This is a quick and dirty test to check if anything at all is working.
+ *
+ * Depends on the scott/tiger schema availble here:
+ * https://github.com/oracle/dotnet-db-samples/blob/master/schemas/scott.sql
+ */
+public class FirstLight {
+
+ //
+ // EDIT THESE
+ //
+ // Define these three constants with the appropriate values for the database
+ // and JDBC driver you want to use. Should work with ANY reasonably standard
+ // JDBC driver. These values are passed to DriverManager.getConnection.
+ public static final String URL = "jdbc:oracle:thin:@//den03cll.us.oracle.com:5521/main2.regress.rdbms.dev.us.oracle.com"; //"";
+ public static final String USER = "scott"; //";
+ public static final String PASSWORD = "tiger"; //";
+ // Define this to be the most trivial SELECT possible
+ public static final String TRIVIAL = "SELECT 1 FROM DUAL";
+
+
+ public static final String FACTORY_NAME = "com.oracle.adbaoverjdbc.DataSourceFactory";
+
+ public FirstLight() {
+ }
+
+ @BeforeClass
+ public static void setUpClass() {
+ }
+
+ @AfterClass
+ public static void tearDownClass() {
+ }
+
+ @Before
+ public void setUp() {
+ }
+
+ @After
+ public void tearDown() {
+ }
+
+ /**
+ * Verify that DataSourceFactory.forName works. Can't do anything without that.
+ */
+ @Test
+ public void firstLight() {
+ assertEquals("com.oracle.adbaoverjdbc.DataSourceFactory",
+ DataSourceFactory.forName(FACTORY_NAME).getClass().getName());
+ }
+
+ /**
+ * Verify that can create a DataSource, though not a Connection. Should work
+ * even if there is no database.
+ */
+ @Test
+ public void createDataSource() {
+ DataSourceFactory factory = DataSourceFactory.forName(FACTORY_NAME);
+ DataSource ds = factory.builder()
+ .url(URL)
+ .username(USER)
+ .password(PASSWORD)
+ .build();
+ assertNotNull(ds);
+ }
+
+ /**
+ * create a Connection and send a SQL to the database
+ */
+ @Test
+ public void sqlOperation() {
+ Properties props = new Properties();
+ props.setProperty("oracle.jdbc.implicitStatementCacheSize", "10");
+ DataSourceFactory factory = DataSourceFactory.forName(FACTORY_NAME);
+ DataSource ds = factory.builder()
+ .url(URL)
+ .username(USER)
+ .password(PASSWORD)
+ .connectionProperty(JDBC_CONNECTION_PROPERTIES, props)
+ .build();
+ Connection conn = ds.getConnection(t -> System.out.println("ERROR: " + t.getMessage()));
+ try (conn) {
+ assertNotNull(conn);
+ conn.operation(TRIVIAL).submit();
+ }
+ ForkJoinPool.commonPool().awaitQuiescence(1, TimeUnit.MINUTES);
+ }
+
+ /**
+ * Execute a few trivial queries.
+ */
+ @Test
+ public void rowOperation() {
+ Properties props = new Properties();
+ props.setProperty("oracle.jdbc.implicitStatementCacheSize", "10");
+ DataSourceFactory factory = DataSourceFactory.forName(FACTORY_NAME);
+ try (DataSource ds = factory.builder()
+ .url(URL)
+ .username(USER)
+ .password(PASSWORD)
+ .connectionProperty(JDBC_CONNECTION_PROPERTIES, props)
+ .build();
+ Connection conn = ds.getConnection(t -> System.out.println("ERROR: " + t.getMessage()))) {
+ assertNotNull(conn);
+ conn.rowOperation(TRIVIAL)
+ .collect(Collector.of(() -> null,
+ (a, r) -> {
+ System.out.println("Trivial: " + r.get("1", String.class));
+ },
+ (x, y) -> null))
+ .submit();
+ conn.rowOperation("select * from emp")
+ .collect(Collector.of(
+ () -> new int[1],
+ (int[] a, Result.Row r) -> {
+ a[0] = a[0]+r.get("sal", Integer.class);
+ },
+ (l, r) -> l,
+ a -> (Integer)a[0]))
+ .submit()
+ .getCompletionStage()
+ .thenAccept( n -> {System.out.println("labor cost: " + n);})
+ .toCompletableFuture();
+ conn.rowOperation("select * from emp where empno = ?")
+ .set("1", 7782)
+ .collect(Collector.of(
+ () -> null,
+ (a, r) -> {
+ System.out.println("salary: $" + r.get("sal", Integer.class));
+ },
+ (l, r) -> null))
+ .submit();
+ }
+ ForkJoinPool.commonPool().awaitQuiescence(1, TimeUnit.MINUTES);
+ }
+
+ /**
+ * check does error handling do anything
+ */
+ @Test
+ public void errorHandling() {
+ Properties props = new Properties();
+ props.setProperty("oracle.jdbc.implicitStatementCacheSize", "10");
+ DataSourceFactory factory = DataSourceFactory.forName(FACTORY_NAME);
+ try (DataSource ds = factory.builder()
+ .url(URL)
+ .username(USER)
+ .password("invalid password")
+ .connectionProperty(JDBC_CONNECTION_PROPERTIES, props)
+ .build();
+ Connection conn = ds.getConnection(t -> System.out.println("ERROR: " + t.toString()))) {
+ conn.rowOperation(TRIVIAL)
+ .collect(Collector.of(() -> null,
+ (a, r) -> {
+ System.out.println("Trivial: " + r.get("1", String.class));
+ },
+ (x, y) -> null))
+ .onError( t -> { System.out.println(t.toString()); })
+ .submit();
+ }
+
+ try (DataSource ds = factory.builder()
+ .url(URL)
+ .username(USER)
+ .password(PASSWORD)
+ .connectionProperty(JDBC_CONNECTION_PROPERTIES, props)
+ .build();
+ Connection conn = ds.getConnection(t -> System.out.println("ERROR: " + t.toString()))) {
+ conn.rowOperation("select * from emp where empno = ?")
+ .set("1", 7782)
+ .collect(Collector.of(
+ () -> null,
+ (a, r) -> {
+ System.out.println("salary: $" + r.get("sal", Integer.class));
+ },
+ (l, r) -> null))
+ .onError( t -> { System.out.println(t.getMessage()); } )
+ .submit();
+ }
+ ForkJoinPool.commonPool().awaitQuiescence(1, TimeUnit.MINUTES);
+ }
+
+ /**
+ * Do something that approximates real work. Do a transaction. Uses
+ * Transaction, CompletionStage args, and catch Operation.
+ */
+ @Test
+ public void transaction() {
+ Properties props = new Properties();
+ props.setProperty("oracle.jdbc.implicitStatementCacheSize", "10");
+ DataSourceFactory factory = DataSourceFactory.forName(FACTORY_NAME);
+ try (DataSource ds = factory.builder()
+ .url(URL)
+ .username(USER)
+ .password(PASSWORD)
+ .connectionProperty(JDBC_CONNECTION_PROPERTIES, props)
+ .build();
+ Connection conn = ds.getConnection(t -> System.out.println("ERROR: " + t.toString()))) {
+ Transaction trans = conn.transaction();
+ CompletionStage idF = conn.rowOperation("select empno, ename from emp where ename = ? for update")
+ .set("1", "CLARK", AdbaType.VARCHAR)
+ .collect(Collector.of(
+ () -> new int[1],
+ (a, r) -> {a[0] = r.get("empno", Integer.class); },
+ (l, r) -> null,
+ a -> a[0])
+ )
+ .submit()
+ .getCompletionStage();
+ idF.thenAccept( id -> { System.out.println("id: " + id); } );
+ conn.countOperation("update emp set deptno = ? where empno = ?")
+ .set("1", 50, AdbaType.INTEGER)
+ .set("2", idF, AdbaType.INTEGER)
+ .apply(c -> {
+ if (c.getCount() != 1L) {
+ trans.setRollbackOnly();
+ throw new SqlException("updated wrong number of rows", null, null, -1, null, -1);
+ }
+ return c.getCount();
+ })
+ .onError(t -> t.printStackTrace())
+ .submit()
+ .getCompletionStage()
+ .thenAccept( c -> { System.out.println("updated rows: " + c); } );
+ conn.catchErrors();
+ conn.commitMaybeRollback(trans);
+ }
+ ForkJoinPool.commonPool().awaitQuiescence(1, TimeUnit.MINUTES);
+ }
+}
From 91a976025bdc84b9150d3526db74da24d24ce447 Mon Sep 17 00:00:00 2001
From: Kuassi Mensah
Date: Tue, 10 Apr 2018 13:09:05 -0700
Subject: [PATCH 03/92] Fixed the connect string URL
---
java/AoJ/test/com/oracle/adbaoverjdbc/test/FirstLight.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/java/AoJ/test/com/oracle/adbaoverjdbc/test/FirstLight.java b/java/AoJ/test/com/oracle/adbaoverjdbc/test/FirstLight.java
index 859c98b2..0c6f289e 100644
--- a/java/AoJ/test/com/oracle/adbaoverjdbc/test/FirstLight.java
+++ b/java/AoJ/test/com/oracle/adbaoverjdbc/test/FirstLight.java
@@ -49,7 +49,7 @@ public class FirstLight {
// Define these three constants with the appropriate values for the database
// and JDBC driver you want to use. Should work with ANY reasonably standard
// JDBC driver. These values are passed to DriverManager.getConnection.
- public static final String URL = "jdbc:oracle:thin:@//den03cll.us.oracle.com:5521/main2.regress.rdbms.dev.us.oracle.com"; //"";
+ public static final String URL = "”;
public static final String USER = "scott"; //";
public static final String PASSWORD = "tiger"; //";
// Define this to be the most trivial SELECT possible
From a363b728512c5c06f1ffb14cfc9c07d8652fdbfb Mon Sep 17 00:00:00 2001
From: Kuassi Mensah
Date: Wed, 11 Apr 2018 08:50:07 -0700
Subject: [PATCH 04/92] Replaced curly braket with doubled quote
---
java/AoJ/test/com/oracle/adbaoverjdbc/test/FirstLight.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/java/AoJ/test/com/oracle/adbaoverjdbc/test/FirstLight.java b/java/AoJ/test/com/oracle/adbaoverjdbc/test/FirstLight.java
index 0c6f289e..b54254ec 100644
--- a/java/AoJ/test/com/oracle/adbaoverjdbc/test/FirstLight.java
+++ b/java/AoJ/test/com/oracle/adbaoverjdbc/test/FirstLight.java
@@ -49,7 +49,7 @@ public class FirstLight {
// Define these three constants with the appropriate values for the database
// and JDBC driver you want to use. Should work with ANY reasonably standard
// JDBC driver. These values are passed to DriverManager.getConnection.
- public static final String URL = "”;
+ public static final String URL = "";
public static final String USER = "scott"; //";
public static final String PASSWORD = "tiger"; //";
// Define this to be the most trivial SELECT possible
From 54eddb732dc8f7f29fe7a5c2c9c276c764b987f9 Mon Sep 17 00:00:00 2001
From: Kuassi Mensah
Date: Wed, 11 Apr 2018 08:53:32 -0700
Subject: [PATCH 05/92] Added ADBA JavaDoc
---
java/AoJ/README.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/java/AoJ/README.md b/java/AoJ/README.md
index 64b3089b..b4205789 100644
--- a/java/AoJ/README.md
+++ b/java/AoJ/README.md
@@ -2,6 +2,7 @@
ADBA is Asynchronous Database Access, a non-blocking database access api that Oracle is proposing as a Java standard. ADBA was announced at [JavaOne 2016](https://static.rainfocus.com/oracle/oow16/sess/1461693351182001EmRq/ppt/CONF1578%2020160916.pdf) and presented again at [JavaOne 2017](http://www.oracle.com/technetwork/database/application-development/jdbc/con1491-3961036.pdf). The ADBA source is available for download from the [OpenJDK sandbox](
http://hg.openjdk.java.net/jdk/sandbox/file/9d3b0eb749a9/src/jdk.incubator.adba) as part of the OpenJDK project. You can get involved in the ADBA specification effort by following the [JDBC Expert Group mailing list](http://mail.openjdk.java.net/pipermail/jdbc-spec-discuss/).
+The ADBA Javadoc is [here](http://cr.openjdk.java.net/~lancea/8188051/apidoc/jdk.incubator.adba-summary.html)
Reading a bunch of JavaDoc and interfaces can be interesting, but it is not nearly as engaging as having actual running code to play with. To that end, we have uploaded the beginnings of an implementation of ADBA running over standard JDBC, AoJ. AoJ is available for download from [GitHub](https://github.com/oracle/oracle-db-examples/tree/master/java/AoJ) under the Apache license. It should run with any reasonably standard compliant JDBC driver.
From 3054a6987589aeb535d7c484bd8ffeb56cb85f4f Mon Sep 17 00:00:00 2001
From: Dan McGhan
Date: Wed, 11 Apr 2018 13:36:25 -0400
Subject: [PATCH 06/92] Added part 4 - handling post, put and delete requests
---
.../hr_app/config/database.js | 10 +
.../hr_app/config/web-server.js | 3 +
.../hr_app/controllers/employees.js | 95 +++++
.../hr_app/db_apis/employees.js | 131 ++++++
.../hr_app/index.js | 86 ++++
.../hr_app/package-lock.json | 392 ++++++++++++++++++
.../hr_app/package.json | 16 +
.../hr_app/services/database.js | 43 ++
.../hr_app/services/router.js | 11 +
.../hr_app/services/web-server.js | 64 +++
10 files changed, 851 insertions(+)
create mode 100644 javascript/rest-api/part-4-handling-post-put-and-delete-requests/hr_app/config/database.js
create mode 100644 javascript/rest-api/part-4-handling-post-put-and-delete-requests/hr_app/config/web-server.js
create mode 100644 javascript/rest-api/part-4-handling-post-put-and-delete-requests/hr_app/controllers/employees.js
create mode 100644 javascript/rest-api/part-4-handling-post-put-and-delete-requests/hr_app/db_apis/employees.js
create mode 100644 javascript/rest-api/part-4-handling-post-put-and-delete-requests/hr_app/index.js
create mode 100644 javascript/rest-api/part-4-handling-post-put-and-delete-requests/hr_app/package-lock.json
create mode 100644 javascript/rest-api/part-4-handling-post-put-and-delete-requests/hr_app/package.json
create mode 100644 javascript/rest-api/part-4-handling-post-put-and-delete-requests/hr_app/services/database.js
create mode 100644 javascript/rest-api/part-4-handling-post-put-and-delete-requests/hr_app/services/router.js
create mode 100644 javascript/rest-api/part-4-handling-post-put-and-delete-requests/hr_app/services/web-server.js
diff --git a/javascript/rest-api/part-4-handling-post-put-and-delete-requests/hr_app/config/database.js b/javascript/rest-api/part-4-handling-post-put-and-delete-requests/hr_app/config/database.js
new file mode 100644
index 00000000..40831f85
--- /dev/null
+++ b/javascript/rest-api/part-4-handling-post-put-and-delete-requests/hr_app/config/database.js
@@ -0,0 +1,10 @@
+module.exports = {
+ hrPool: {
+ user: process.env.HR_USER,
+ password: process.env.HR_PASSWORD,
+ connectString: process.env.HR_CONNECTIONSTRING,
+ poolMin: 10,
+ poolMax: 10,
+ poolIncrement: 0
+ }
+};
diff --git a/javascript/rest-api/part-4-handling-post-put-and-delete-requests/hr_app/config/web-server.js b/javascript/rest-api/part-4-handling-post-put-and-delete-requests/hr_app/config/web-server.js
new file mode 100644
index 00000000..ff74b593
--- /dev/null
+++ b/javascript/rest-api/part-4-handling-post-put-and-delete-requests/hr_app/config/web-server.js
@@ -0,0 +1,3 @@
+module.exports = {
+ port: process.env.HTTP_PORT || 3000
+};
diff --git a/javascript/rest-api/part-4-handling-post-put-and-delete-requests/hr_app/controllers/employees.js b/javascript/rest-api/part-4-handling-post-put-and-delete-requests/hr_app/controllers/employees.js
new file mode 100644
index 00000000..81c521d5
--- /dev/null
+++ b/javascript/rest-api/part-4-handling-post-put-and-delete-requests/hr_app/controllers/employees.js
@@ -0,0 +1,95 @@
+const employees = require('../db_apis/employees.js');
+
+async function get(req, res, next) {
+ try {
+ const context = {};
+
+ context.id = Number(req.params.id);
+
+ const rows = await employees.find(context);
+
+ if (req.params.id) {
+ if (rows.length === 1) {
+ res.status(200).json(rows[0]);
+ } else {
+ res.status(404).end();
+ }
+ } else {
+ res.status(200).json(rows);
+ }
+ } catch (err) {
+ next(err);
+ }
+}
+
+module.exports.get = get;
+
+function getEmployeeFromRec(req) {
+ const employee = {
+ first_name: req.body.first_name,
+ last_name: req.body.last_name,
+ email: req.body.email,
+ phone_number: req.body.phone_number,
+ hire_date: req.body.hire_date,
+ job_id: req.body.job_id,
+ salary: req.body.salary,
+ commission_pct: req.body.commission_pct,
+ manager_id: req.body.manager_id,
+ department_id: req.body.department_id
+ };
+
+ return employee;
+}
+
+async function post(req, res, next) {
+ try {
+ let employee = getEmployeeFromRec(req);
+
+ employee = await employees.create(employee);
+
+ res.status(201).json(employee);
+ } catch (err) {
+ next(err);
+ }
+}
+
+module.exports.post = post;
+
+async function put(req, res, next) {
+ try {
+ let employee = getEmployeeFromRec(req);
+
+ employee.employee_id = parseInt(req.params.id, 10);
+
+ employee = await employees.update(employee);
+
+ if (employee !== null) {
+ res.status(200).json(employee);
+ } else {
+ res.status(404).end();
+ }
+ } catch (err) {
+ next(err);
+ }
+}
+
+module.exports.put = put;
+
+async function del(req, res, next) {
+ try {
+ const id = parseInt(req.params.id, 10);
+
+ const success = await employees.delete(id);
+
+ if (success) {
+ res.status(204).end();
+ } else {
+ res.status(404).end();
+ }
+ } catch (err) {
+ next(err);
+ }
+}
+
+module.exports.delete = del;
+
diff --git a/javascript/rest-api/part-4-handling-post-put-and-delete-requests/hr_app/db_apis/employees.js b/javascript/rest-api/part-4-handling-post-put-and-delete-requests/hr_app/db_apis/employees.js
new file mode 100644
index 00000000..5e02d3f6
--- /dev/null
+++ b/javascript/rest-api/part-4-handling-post-put-and-delete-requests/hr_app/db_apis/employees.js
@@ -0,0 +1,131 @@
+const oracledb = require('oracledb');
+const database = require('../services/database.js');
+
+const baseQuery =
+ `select employee_id "id",
+ first_name "first_name",
+ last_name "last_name",
+ email "email",
+ phone_number "phone_number",
+ hire_date "hire_date",
+ job_id "job_id",
+ salary "salary",
+ commission_pct "commission_pct",
+ manager_id "manager_id",
+ department_id "department_id"
+ from employees`;
+
+async function find(context) {
+ let query = baseQuery;
+ const binds = {};
+
+ if (context.id) {
+ binds.employee_id = context.id;
+
+ query += `\nwhere employee_id = :employee_id`;
+ }
+
+ const result = await database.simpleExecute(query, binds);
+
+ return result.rows;
+}
+
+module.exports.find = find;
+
+const createSql =
+ `insert into employees (
+ first_name,
+ last_name,
+ email,
+ phone_number,
+ hire_date,
+ job_id,
+ salary,
+ commission_pct,
+ manager_id,
+ department_id
+ ) values (
+ :first_name,
+ :last_name,
+ :email,
+ :phone_number,
+ :hire_date,
+ :job_id,
+ :salary,
+ :commission_pct,
+ :manager_id,
+ :department_id
+ ) returning employee_id
+ into :employee_id`;
+
+async function create(emp) {
+ const employee = Object.assign({}, emp);
+
+ employee.employee_id = {
+ dir: oracledb.BIND_OUT,
+ type: oracledb.NUMBER
+ }
+
+ const result = await database.simpleExecute(createSql, employee);
+
+ employee.employee_id = result.outBinds.employee_id[0];
+
+ return employee;
+}
+
+module.exports.create = create;
+
+const updateSql =
+ `update employees
+ set first_name = :first_name,
+ last_name = :last_name,
+ email = :email,
+ phone_number = :phone_number,
+ hire_date = :hire_date,
+ job_id = :job_id,
+ salary = :salary,
+ commission_pct = :commission_pct,
+ manager_id = :manager_id,
+ department_id = :department_id
+ where employee_id = :employee_id`;
+
+async function update(emp) {
+ const employee = Object.assign({}, emp);
+ const result = await database.simpleExecute(updateSql, employee);
+
+ if (result.rowsAffected === 1) {
+ return employee;
+ } else {
+ return null;
+ }
+}
+
+module.exports.update = update;
+
+const deleteSql =
+ `begin
+
+ delete from job_history
+ where employee_id = :employee_id;
+
+ delete from employees
+ where employee_id = :employee_id;
+
+ :rowcount := sql%rowcount;
+
+ end;`
+
+async function del(id) {
+ const binds = {
+ employee_id: id,
+ rowcount: {
+ dir: oracledb.BIND_OUT,
+ type: oracledb.NUMBER
+ }
+ }
+ const result = await database.simpleExecute(deleteSql, binds);
+
+ return result.outBinds.rowcount === 1;
+}
+
+module.exports.delete = del;
diff --git a/javascript/rest-api/part-4-handling-post-put-and-delete-requests/hr_app/index.js b/javascript/rest-api/part-4-handling-post-put-and-delete-requests/hr_app/index.js
new file mode 100644
index 00000000..0eba3fad
--- /dev/null
+++ b/javascript/rest-api/part-4-handling-post-put-and-delete-requests/hr_app/index.js
@@ -0,0 +1,86 @@
+const webServer = require('./services/web-server.js');
+const database = require('./services/database.js');
+const dbConfig = require('./config/database.js');
+const defaultThreadPoolSize = 4;
+
+// Increase thread pool size by poolMax
+process.env.UV_THREADPOOL_SIZE = dbConfig.hrPool.poolMax + defaultThreadPoolSize;
+
+async function startup() {
+ console.log('Starting application');
+
+ try {
+ console.log('Initializing database module');
+
+ await database.initialize();
+ } catch (err) {
+ console.error(err);
+
+ process.exit(1); // Non-zero failure code
+ }
+
+ try {
+ console.log('Initializing web server module');
+
+ await webServer.initialize();
+ } catch (err) {
+ console.error(err);
+
+ process.exit(1); // Non-zero failure code
+ }
+}
+
+startup();
+
+async function shutdown(e) {
+ let err = e;
+
+ console.log('Shutting down application');
+
+ try {
+ console.log('Closing web server module');
+
+ await webServer.close();
+ } catch (e) {
+ console.error(e);
+
+ err = err || e;
+ }
+
+ try {
+ console.log('Closing database module');
+
+ await database.close();
+ } catch (e) {
+ console.error(e);
+
+ err = err || e;
+ }
+
+ console.log('Exiting process');
+
+ if (err) {
+ process.exit(1); // Non-zero failure code
+ } else {
+ process.exit(0);
+ }
+}
+
+process.on('SIGTERM', () => {
+ console.log('Received SIGTERM');
+
+ shutdown();
+});
+
+process.on('SIGINT', () => {
+ console.log('Received SIGINT');
+
+ shutdown();
+});
+
+process.on('uncaughtException', err => {
+ console.log('Uncaught exception');
+ console.error(err);
+
+ shutdown(err);
+});
diff --git a/javascript/rest-api/part-4-handling-post-put-and-delete-requests/hr_app/package-lock.json b/javascript/rest-api/part-4-handling-post-put-and-delete-requests/hr_app/package-lock.json
new file mode 100644
index 00000000..c2f35b4f
--- /dev/null
+++ b/javascript/rest-api/part-4-handling-post-put-and-delete-requests/hr_app/package-lock.json
@@ -0,0 +1,392 @@
+{
+ "name": "hr_app",
+ "version": "0.1.0",
+ "lockfileVersion": 1,
+ "requires": true,
+ "dependencies": {
+ "accepts": {
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz",
+ "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=",
+ "requires": {
+ "mime-types": "2.1.18",
+ "negotiator": "0.6.1"
+ }
+ },
+ "array-flatten": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+ "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
+ },
+ "basic-auth": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.0.tgz",
+ "integrity": "sha1-AV2z81PgLlY3d1X5YnQuiYHnu7o=",
+ "requires": {
+ "safe-buffer": "5.1.1"
+ }
+ },
+ "body-parser": {
+ "version": "1.18.2",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz",
+ "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=",
+ "requires": {
+ "bytes": "3.0.0",
+ "content-type": "1.0.4",
+ "debug": "2.6.9",
+ "depd": "1.1.2",
+ "http-errors": "1.6.2",
+ "iconv-lite": "0.4.19",
+ "on-finished": "2.3.0",
+ "qs": "6.5.1",
+ "raw-body": "2.3.2",
+ "type-is": "1.6.16"
+ }
+ },
+ "bytes": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
+ "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg="
+ },
+ "content-disposition": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz",
+ "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ="
+ },
+ "content-type": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
+ "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
+ },
+ "cookie": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
+ "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s="
+ },
+ "cookie-signature": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+ "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
+ },
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "depd": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+ "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
+ },
+ "destroy": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
+ "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
+ },
+ "ee-first": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
+ },
+ "encodeurl": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+ "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
+ },
+ "escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
+ },
+ "etag": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+ "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
+ },
+ "express": {
+ "version": "4.16.3",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.16.3.tgz",
+ "integrity": "sha1-avilAjUNsyRuzEvs9rWjTSL37VM=",
+ "requires": {
+ "accepts": "1.3.5",
+ "array-flatten": "1.1.1",
+ "body-parser": "1.18.2",
+ "content-disposition": "0.5.2",
+ "content-type": "1.0.4",
+ "cookie": "0.3.1",
+ "cookie-signature": "1.0.6",
+ "debug": "2.6.9",
+ "depd": "1.1.2",
+ "encodeurl": "1.0.2",
+ "escape-html": "1.0.3",
+ "etag": "1.8.1",
+ "finalhandler": "1.1.1",
+ "fresh": "0.5.2",
+ "merge-descriptors": "1.0.1",
+ "methods": "1.1.2",
+ "on-finished": "2.3.0",
+ "parseurl": "1.3.2",
+ "path-to-regexp": "0.1.7",
+ "proxy-addr": "2.0.3",
+ "qs": "6.5.1",
+ "range-parser": "1.2.0",
+ "safe-buffer": "5.1.1",
+ "send": "0.16.2",
+ "serve-static": "1.13.2",
+ "setprototypeof": "1.1.0",
+ "statuses": "1.4.0",
+ "type-is": "1.6.16",
+ "utils-merge": "1.0.1",
+ "vary": "1.1.2"
+ }
+ },
+ "finalhandler": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz",
+ "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==",
+ "requires": {
+ "debug": "2.6.9",
+ "encodeurl": "1.0.2",
+ "escape-html": "1.0.3",
+ "on-finished": "2.3.0",
+ "parseurl": "1.3.2",
+ "statuses": "1.4.0",
+ "unpipe": "1.0.0"
+ }
+ },
+ "forwarded": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
+ "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
+ },
+ "fresh": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+ "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
+ },
+ "http-errors": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz",
+ "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=",
+ "requires": {
+ "depd": "1.1.1",
+ "inherits": "2.0.3",
+ "setprototypeof": "1.0.3",
+ "statuses": "1.4.0"
+ },
+ "dependencies": {
+ "depd": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz",
+ "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k="
+ },
+ "setprototypeof": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz",
+ "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ="
+ }
+ }
+ },
+ "iconv-lite": {
+ "version": "0.4.19",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
+ "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ=="
+ },
+ "inherits": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
+ },
+ "ipaddr.js": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.6.0.tgz",
+ "integrity": "sha1-4/o1e3c9phnybpXwSdBVxyeW+Gs="
+ },
+ "media-typer": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+ "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
+ },
+ "merge-descriptors": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
+ "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
+ },
+ "methods": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+ "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
+ },
+ "mime": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
+ "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ=="
+ },
+ "mime-db": {
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz",
+ "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ=="
+ },
+ "mime-types": {
+ "version": "2.1.18",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz",
+ "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==",
+ "requires": {
+ "mime-db": "1.33.0"
+ }
+ },
+ "morgan": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.0.tgz",
+ "integrity": "sha1-0B+mxlhZt2/PMbPLU6OCGjEdgFE=",
+ "requires": {
+ "basic-auth": "2.0.0",
+ "debug": "2.6.9",
+ "depd": "1.1.2",
+ "on-finished": "2.3.0",
+ "on-headers": "1.0.1"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ },
+ "negotiator": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz",
+ "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk="
+ },
+ "on-finished": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+ "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
+ "requires": {
+ "ee-first": "1.1.1"
+ }
+ },
+ "on-headers": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz",
+ "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c="
+ },
+ "oracledb": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/oracledb/-/oracledb-2.2.0.tgz",
+ "integrity": "sha512-ywwalyryeJYb5dr1JScyPcNxCeN0zExrKLtorSdptBZqhfS5Dp9KLgGOExc+XMMfEejXGtC/RfiDxKaGn6+VJA=="
+ },
+ "parseurl": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
+ "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M="
+ },
+ "path-to-regexp": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
+ "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
+ },
+ "proxy-addr": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.3.tgz",
+ "integrity": "sha512-jQTChiCJteusULxjBp8+jftSQE5Obdl3k4cnmLA6WXtK6XFuWRnvVL7aCiBqaLPM8c4ph0S4tKna8XvmIwEnXQ==",
+ "requires": {
+ "forwarded": "0.1.2",
+ "ipaddr.js": "1.6.0"
+ }
+ },
+ "qs": {
+ "version": "6.5.1",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
+ "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A=="
+ },
+ "range-parser": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
+ "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4="
+ },
+ "raw-body": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz",
+ "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=",
+ "requires": {
+ "bytes": "3.0.0",
+ "http-errors": "1.6.2",
+ "iconv-lite": "0.4.19",
+ "unpipe": "1.0.0"
+ }
+ },
+ "safe-buffer": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
+ "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
+ },
+ "send": {
+ "version": "0.16.2",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz",
+ "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==",
+ "requires": {
+ "debug": "2.6.9",
+ "depd": "1.1.2",
+ "destroy": "1.0.4",
+ "encodeurl": "1.0.2",
+ "escape-html": "1.0.3",
+ "etag": "1.8.1",
+ "fresh": "0.5.2",
+ "http-errors": "1.6.2",
+ "mime": "1.4.1",
+ "ms": "2.0.0",
+ "on-finished": "2.3.0",
+ "range-parser": "1.2.0",
+ "statuses": "1.4.0"
+ }
+ },
+ "serve-static": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz",
+ "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==",
+ "requires": {
+ "encodeurl": "1.0.2",
+ "escape-html": "1.0.3",
+ "parseurl": "1.3.2",
+ "send": "0.16.2"
+ }
+ },
+ "setprototypeof": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
+ "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ=="
+ },
+ "statuses": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz",
+ "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew=="
+ },
+ "type-is": {
+ "version": "1.6.16",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz",
+ "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==",
+ "requires": {
+ "media-typer": "0.3.0",
+ "mime-types": "2.1.18"
+ }
+ },
+ "unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
+ },
+ "utils-merge": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+ "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
+ },
+ "vary": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+ "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
+ }
+ }
+}
diff --git a/javascript/rest-api/part-4-handling-post-put-and-delete-requests/hr_app/package.json b/javascript/rest-api/part-4-handling-post-put-and-delete-requests/hr_app/package.json
new file mode 100644
index 00000000..44dc8bc0
--- /dev/null
+++ b/javascript/rest-api/part-4-handling-post-put-and-delete-requests/hr_app/package.json
@@ -0,0 +1,16 @@
+{
+ "name": "hr_app",
+ "version": "0.1.0",
+ "description": "Creating a REST API with Node.js and Oracle Database",
+ "main": "index.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "keywords": [],
+ "license": "Apache-2.0",
+ "dependencies": {
+ "express": "^4.16.3",
+ "morgan": "^1.9.0",
+ "oracledb": "^2.2.0"
+ }
+}
diff --git a/javascript/rest-api/part-4-handling-post-put-and-delete-requests/hr_app/services/database.js b/javascript/rest-api/part-4-handling-post-put-and-delete-requests/hr_app/services/database.js
new file mode 100644
index 00000000..d7cb8e0a
--- /dev/null
+++ b/javascript/rest-api/part-4-handling-post-put-and-delete-requests/hr_app/services/database.js
@@ -0,0 +1,43 @@
+const oracledb = require('oracledb');
+const dbConfig = require('../config/database.js');
+
+async function initialize() {
+ await oracledb.createPool(dbConfig.hrPool);
+}
+
+module.exports.initialize = initialize;
+
+async function close() {
+ await oracledb.getPool().close();
+}
+
+module.exports.close = close;
+
+function simpleExecute(statement, binds = [], opts = {}) {
+ return new Promise(async (resolve, reject) => {
+ let conn;
+
+ opts.outFormat = oracledb.OBJECT;
+ opts.autoCommit = true;
+
+ try {
+ conn = await oracledb.getConnection();
+
+ const result = await conn.execute(statement, binds, opts);
+
+ resolve(result);
+ } catch (err) {
+ reject(err);
+ } finally {
+ if (conn) { // conn assignment worked, need to close
+ try {
+ await conn.close();
+ } catch (err) {
+ console.log(err);
+ }
+ }
+ }
+ });
+}
+
+module.exports.simpleExecute = simpleExecute;
diff --git a/javascript/rest-api/part-4-handling-post-put-and-delete-requests/hr_app/services/router.js b/javascript/rest-api/part-4-handling-post-put-and-delete-requests/hr_app/services/router.js
new file mode 100644
index 00000000..e3d9011f
--- /dev/null
+++ b/javascript/rest-api/part-4-handling-post-put-and-delete-requests/hr_app/services/router.js
@@ -0,0 +1,11 @@
+const express = require('express');
+const router = new express.Router();
+const employees = require('../controllers/employees.js');
+
+router.route('/employees/:id?')
+ .get(employees.get)
+ .post(employees.post)
+ .put(employees.put)
+ .delete(employees.delete);
+
+module.exports = router;
diff --git a/javascript/rest-api/part-4-handling-post-put-and-delete-requests/hr_app/services/web-server.js b/javascript/rest-api/part-4-handling-post-put-and-delete-requests/hr_app/services/web-server.js
new file mode 100644
index 00000000..c509b646
--- /dev/null
+++ b/javascript/rest-api/part-4-handling-post-put-and-delete-requests/hr_app/services/web-server.js
@@ -0,0 +1,64 @@
+const http = require('http');
+const express = require('express');
+const morgan = require('morgan');
+const webServerConfig = require('../config/web-server.js');
+const router = require('./router.js');
+
+let httpServer;
+
+function initialize() {
+ return new Promise((resolve, reject) => {
+ const app = express();
+ httpServer = http.createServer(app);
+
+ // Combines logging info from request and response
+ app.use(morgan('combined'));
+
+ // Parse incoming JSON requests and revive JSON.
+ app.use(express.json({
+ reviver: reviveJson
+ }));
+
+ // Mount the router at /api so all its routes start with /api
+ app.use('/api', router);
+
+ httpServer.listen(webServerConfig.port, err => {
+ if (err) {
+ reject(err);
+ return;
+ }
+
+ console.log(`Web server listening on localhost:${webServerConfig.port}`);
+
+ resolve();
+ });
+ });
+}
+
+module.exports.initialize = initialize;
+
+function close() {
+ return new Promise((resolve, reject) => {
+ httpServer.close((err) => {
+ if (err) {
+ reject(err);
+ return;
+ }
+
+ resolve();
+ });
+ });
+}
+
+module.exports.close = close;
+
+const iso8601RegExp = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{3})?Z$/;
+
+function reviveJson(key, value) {
+ // revive ISO 8601 date strings to instances of Date
+ if (typeof value === 'string' && iso8601RegExp.test(value)) {
+ return new Date(value);
+ } else {
+ return value;
+ }
+}
From 29ee0b11c0d10ec48e4b70b06cd579bffb840f91 Mon Sep 17 00:00:00 2001
From: Dan McGhan
Date: Wed, 11 Apr 2018 13:40:35 -0400
Subject: [PATCH 07/92] Changed Number to parseInt for primitive value
---
.../hr_app/controllers/employees.js | 2 +-
.../hr_app/controllers/employees.js | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/javascript/rest-api/part-3-handling-get-requests/hr_app/controllers/employees.js b/javascript/rest-api/part-3-handling-get-requests/hr_app/controllers/employees.js
index a5257c6c..2310cf62 100644
--- a/javascript/rest-api/part-3-handling-get-requests/hr_app/controllers/employees.js
+++ b/javascript/rest-api/part-3-handling-get-requests/hr_app/controllers/employees.js
@@ -4,7 +4,7 @@ async function get(req, res, next) {
try {
const context = {};
- context.id = Number(req.params.id);
+ context.id = parseInt(req.params.id, 10);
const rows = await employees.find(context);
diff --git a/javascript/rest-api/part-4-handling-post-put-and-delete-requests/hr_app/controllers/employees.js b/javascript/rest-api/part-4-handling-post-put-and-delete-requests/hr_app/controllers/employees.js
index 81c521d5..b22bae5e 100644
--- a/javascript/rest-api/part-4-handling-post-put-and-delete-requests/hr_app/controllers/employees.js
+++ b/javascript/rest-api/part-4-handling-post-put-and-delete-requests/hr_app/controllers/employees.js
@@ -4,7 +4,7 @@ async function get(req, res, next) {
try {
const context = {};
- context.id = Number(req.params.id);
+ context.id = parseInt(req.params.id, 10);
const rows = await employees.find(context);
From fc37001428a9842bdf4c7db3b59bc52fb5e6d88f Mon Sep 17 00:00:00 2001
From: Kuassi Mensah
Date: Fri, 13 Apr 2018 09:20:31 -0700
Subject: [PATCH 08/92] Updated Readme
---
java/AoJ/README.markdown | 120 +++++++++++++++++++++++++++++++++++++++
1 file changed, 120 insertions(+)
create mode 100644 java/AoJ/README.markdown
diff --git a/java/AoJ/README.markdown b/java/AoJ/README.markdown
new file mode 100644
index 00000000..a2492e1a
--- /dev/null
+++ b/java/AoJ/README.markdown
@@ -0,0 +1,120 @@
+# AoJ: ADBA over JDBC
+
+ADBA is Asynchronous Database Access, a non-blocking database access api that
+Oracle is proposing as a Java standard. ADBA was announced at
+[JavaOne 2016](https://static.rainfocus.com/oracle/oow16/sess/1461693351182001EmRq/ppt/CONF1578%2020160916.pdf)
+and presented again at [JavaOne 2017](http://www.oracle.com/technetwork/database/application-development/jdbc/con1491-3961036.pdf).
+The ADBA source is available for download from the [OpenJDK sandbox](http://hg.openjdk.java.net/jdk/sandbox/file/9d3b0eb749a9/src/jdk.incubator.adba)
+as part of the OpenJDK project and the JavaDoc is available [here](http://cr.openjdk.java.net/~lancea/8188051/apidoc/jdk.incubator.adba-summary.html).
+You can get involved in the ADBA specification effort by following the
+[JDBC Expert Group mailing list](http://mail.openjdk.java.net/pipermail/jdbc-spec-discuss/).
+
+Reading a bunch of JavaDoc and interfaces can be interesting, but it is not nearly
+as engaging as having actual running code to play with. To that end, we have
+uploaded the beginnings of an implementation of ADBA running over standard JDBC,
+AoJ. AoJ is available for download from [GitHub](https://github.com/oracle/oracle-db-examples/tree/master/java/AoJ)
+under the Apache license. It should run with any reasonably standard compliant
+JDBC driver.
+
+AoJ implements only a small part of ADBA, but it is enough to write interesting
+code. It provides partial implementations of ```DataSourceFactory```, ```DataSource```,
+```Connection```, ```OperationGroup```, ```RowOperation```, ```CountOperation```,
+```Transaction``` and others. These implementations are not complete but there is
+enough there to write interesting database programs. The code that is there is
+untested, but it does work to some extent. The saving grace is that you can
+download the source and improve it: add new features, fix bugs, try out alternate
+implementations.
+
+Oracle is not proposing AoJ as an open source project. However, because AoJ is
+released under the Apache license, the Java community can fork the code and create
+a true open source project with this upload as a base. Oracle developers may
+contribute when we have time, but this would have to be a Java community effort.
+
+We could have held this code back and worked on it longer. Instead we thought it
+better to get it to the community as soon as we could. We hope that you agree.
+
+## Building AoJ
+
+AoJ and ADBA require JDK 9 or later. Download ADBA from the
+[OpenJDK sandbox](http://hg.openjdk.java.net/jdk/sandbox/file/9d3b0eb749a9/src/jdk.incubator.adba).
+It does not have any dependencies outside of Java SE. Download AoJ from
+[GitHub](https://github.com/oracle/oracle-db-examples/tree/master/java/AoJ). Both
+are modularized so be sure to include the module-info.java files. AoJ depends on
+ADBA. The AoJ sample file depends on JUnit which is included with most IDEs but is
+also available [here](https://github.com/junit-team/junit4).
+
+To run the sample file you will need a SQL database and corresponding JDBC driver. AoJ
+has been run with [Oracle Database 12c](http://www.oracle.com/technetwork/database/enterprise-edition/downloads/index.html)
+and [Oracle Database 12c JDBC](http://www.oracle.com/technetwork/database/application-development/jdbc/downloads/index.html),
+but it should work with any reasonably standard compliant SQL database and JDBC
+driver. The sample file uses the scott/tiger schema available
+[here](https://github.com/oracle/dotnet-db-samples/blob/master/schemas/scott.sql).
+
+Start the database and load ```scott.sql```. Edit ```com.oracle.adbaoverjdbc.test.FirstLight.java```
+and set the constant ```URL``` to an appropriate value. AoJ will pass this value
+to ```java.sql.DriverManager.getConnection```. If you are using a database other
+than Oracle you should change the value of the constant ```TRIVIAL``` to some
+very trivial ```SELECT``` query.
+
+## Sample Code
+
+The following test case should give you some idea of what AoJ can do. It should
+run with any JDBC driver connecting to a database with the scott schema. This is
+the last test in ```com.oracle.adbaoverjdbc.test.FirstLight.java```. For an
+introduction to ADBA see the [JavaOne 2017 presentation](http://www.oracle.com/technetwork/database/application-development/jdbc/con1491-3961036.pdf).
+
+
+``` public void transactionSample() {
+ // get the AoJ DataSourceFactory
+ DataSourceFactory factory = DataSourceFactory.forName("com.oracle.adbaoverjdbc.DataSourceFactory");
+ // get a DataSource and a Connection
+ try (DataSource ds = factory.builder()
+ .url(URL)
+ .username(“scott")
+ .password(“tiger")
+ .build();
+ Connection conn = ds.getConnection(t -> System.out.println("ERROR: " + t.getMessage()))) {
+ // get a Transaction
+ Transaction trans = conn.transaction();
+ // select the EMPNO of CLARK
+ CompletionStage idF = conn.rowOperation("select empno, ename from emp where ename = ? for update")
+ .set("1", "CLARK", AdbaType.VARCHAR)
+ .collect(Collector.of(
+ () -> new int[1],
+ (a, r) -> {a[0] = r.get("empno", Integer.class); },
+ (l, r) -> null,
+ a -> a[0])
+ )
+ .submit()
+ .getCompletionStage();
+ // update CLARK to work in department 50
+ conn.countOperation("update emp set deptno = ? where empno = ?")
+ .set("1", 50, AdbaType.INTEGER)
+ .set("2", idF, AdbaType.INTEGER)
+ .apply(c -> {
+ if (c.getCount() != 1L) {
+ trans.setRollbackOnly();
+ throw new SqlException("updated wrong number of rows", null, null, -1, null, -1);
+ }
+ return c.getCount();
+ })
+ .onError(t -> t.printStackTrace())
+ .submit();
+
+ conn.catchErrors(); // resume normal execution if there were any errors
+ conn.commitMaybeRollback(trans); // commit (or rollback) the transaction
+ }
+ // wait for the async tasks to complete before exiting
+ ForkJoinPool.commonPool().awaitQuiescence(1, TimeUnit.MINUTES);
+ }```
+
+## AoJ Design Spec in 100 words or less
+
+The methods called by the user thread create a network
+([DAG](https://en.wikipedia.org/wiki/Directed_acyclic_graph)) of
+```CompletableFuture```s. These ```CompleteableFuture```s asynchronously execute
+the synchronous JDBC calls and the result processing code provided by the user
+code. By default AoJ uses ```ForkJoinPool.commonPool()``` to execute
+```CompletableFuture```s but the user code can provide another ```Executor```.
+When the ```Connection``` is submitted the root of the ```CompleteableFuture```
+network is completed triggering execution of the rest of the network.
From 5535df875894333570d75cafeb1e5e0efc1ae14b Mon Sep 17 00:00:00 2001
From: Kuassi Mensah
Date: Fri, 13 Apr 2018 09:22:27 -0700
Subject: [PATCH 09/92] Updated Readme.md
---
java/AoJ/README.markdown | 120 --------------------------
java/AoJ/README.md | 176 ++++++++++++++++++++++++++-------------
2 files changed, 120 insertions(+), 176 deletions(-)
delete mode 100644 java/AoJ/README.markdown
diff --git a/java/AoJ/README.markdown b/java/AoJ/README.markdown
deleted file mode 100644
index a2492e1a..00000000
--- a/java/AoJ/README.markdown
+++ /dev/null
@@ -1,120 +0,0 @@
-# AoJ: ADBA over JDBC
-
-ADBA is Asynchronous Database Access, a non-blocking database access api that
-Oracle is proposing as a Java standard. ADBA was announced at
-[JavaOne 2016](https://static.rainfocus.com/oracle/oow16/sess/1461693351182001EmRq/ppt/CONF1578%2020160916.pdf)
-and presented again at [JavaOne 2017](http://www.oracle.com/technetwork/database/application-development/jdbc/con1491-3961036.pdf).
-The ADBA source is available for download from the [OpenJDK sandbox](http://hg.openjdk.java.net/jdk/sandbox/file/9d3b0eb749a9/src/jdk.incubator.adba)
-as part of the OpenJDK project and the JavaDoc is available [here](http://cr.openjdk.java.net/~lancea/8188051/apidoc/jdk.incubator.adba-summary.html).
-You can get involved in the ADBA specification effort by following the
-[JDBC Expert Group mailing list](http://mail.openjdk.java.net/pipermail/jdbc-spec-discuss/).
-
-Reading a bunch of JavaDoc and interfaces can be interesting, but it is not nearly
-as engaging as having actual running code to play with. To that end, we have
-uploaded the beginnings of an implementation of ADBA running over standard JDBC,
-AoJ. AoJ is available for download from [GitHub](https://github.com/oracle/oracle-db-examples/tree/master/java/AoJ)
-under the Apache license. It should run with any reasonably standard compliant
-JDBC driver.
-
-AoJ implements only a small part of ADBA, but it is enough to write interesting
-code. It provides partial implementations of ```DataSourceFactory```, ```DataSource```,
-```Connection```, ```OperationGroup```, ```RowOperation```, ```CountOperation```,
-```Transaction``` and others. These implementations are not complete but there is
-enough there to write interesting database programs. The code that is there is
-untested, but it does work to some extent. The saving grace is that you can
-download the source and improve it: add new features, fix bugs, try out alternate
-implementations.
-
-Oracle is not proposing AoJ as an open source project. However, because AoJ is
-released under the Apache license, the Java community can fork the code and create
-a true open source project with this upload as a base. Oracle developers may
-contribute when we have time, but this would have to be a Java community effort.
-
-We could have held this code back and worked on it longer. Instead we thought it
-better to get it to the community as soon as we could. We hope that you agree.
-
-## Building AoJ
-
-AoJ and ADBA require JDK 9 or later. Download ADBA from the
-[OpenJDK sandbox](http://hg.openjdk.java.net/jdk/sandbox/file/9d3b0eb749a9/src/jdk.incubator.adba).
-It does not have any dependencies outside of Java SE. Download AoJ from
-[GitHub](https://github.com/oracle/oracle-db-examples/tree/master/java/AoJ). Both
-are modularized so be sure to include the module-info.java files. AoJ depends on
-ADBA. The AoJ sample file depends on JUnit which is included with most IDEs but is
-also available [here](https://github.com/junit-team/junit4).
-
-To run the sample file you will need a SQL database and corresponding JDBC driver. AoJ
-has been run with [Oracle Database 12c](http://www.oracle.com/technetwork/database/enterprise-edition/downloads/index.html)
-and [Oracle Database 12c JDBC](http://www.oracle.com/technetwork/database/application-development/jdbc/downloads/index.html),
-but it should work with any reasonably standard compliant SQL database and JDBC
-driver. The sample file uses the scott/tiger schema available
-[here](https://github.com/oracle/dotnet-db-samples/blob/master/schemas/scott.sql).
-
-Start the database and load ```scott.sql```. Edit ```com.oracle.adbaoverjdbc.test.FirstLight.java```
-and set the constant ```URL``` to an appropriate value. AoJ will pass this value
-to ```java.sql.DriverManager.getConnection```. If you are using a database other
-than Oracle you should change the value of the constant ```TRIVIAL``` to some
-very trivial ```SELECT``` query.
-
-## Sample Code
-
-The following test case should give you some idea of what AoJ can do. It should
-run with any JDBC driver connecting to a database with the scott schema. This is
-the last test in ```com.oracle.adbaoverjdbc.test.FirstLight.java```. For an
-introduction to ADBA see the [JavaOne 2017 presentation](http://www.oracle.com/technetwork/database/application-development/jdbc/con1491-3961036.pdf).
-
-
-``` public void transactionSample() {
- // get the AoJ DataSourceFactory
- DataSourceFactory factory = DataSourceFactory.forName("com.oracle.adbaoverjdbc.DataSourceFactory");
- // get a DataSource and a Connection
- try (DataSource ds = factory.builder()
- .url(URL)
- .username(“scott")
- .password(“tiger")
- .build();
- Connection conn = ds.getConnection(t -> System.out.println("ERROR: " + t.getMessage()))) {
- // get a Transaction
- Transaction trans = conn.transaction();
- // select the EMPNO of CLARK
- CompletionStage idF = conn.rowOperation("select empno, ename from emp where ename = ? for update")
- .set("1", "CLARK", AdbaType.VARCHAR)
- .collect(Collector.of(
- () -> new int[1],
- (a, r) -> {a[0] = r.get("empno", Integer.class); },
- (l, r) -> null,
- a -> a[0])
- )
- .submit()
- .getCompletionStage();
- // update CLARK to work in department 50
- conn.countOperation("update emp set deptno = ? where empno = ?")
- .set("1", 50, AdbaType.INTEGER)
- .set("2", idF, AdbaType.INTEGER)
- .apply(c -> {
- if (c.getCount() != 1L) {
- trans.setRollbackOnly();
- throw new SqlException("updated wrong number of rows", null, null, -1, null, -1);
- }
- return c.getCount();
- })
- .onError(t -> t.printStackTrace())
- .submit();
-
- conn.catchErrors(); // resume normal execution if there were any errors
- conn.commitMaybeRollback(trans); // commit (or rollback) the transaction
- }
- // wait for the async tasks to complete before exiting
- ForkJoinPool.commonPool().awaitQuiescence(1, TimeUnit.MINUTES);
- }```
-
-## AoJ Design Spec in 100 words or less
-
-The methods called by the user thread create a network
-([DAG](https://en.wikipedia.org/wiki/Directed_acyclic_graph)) of
-```CompletableFuture```s. These ```CompleteableFuture```s asynchronously execute
-the synchronous JDBC calls and the result processing code provided by the user
-code. By default AoJ uses ```ForkJoinPool.commonPool()``` to execute
-```CompletableFuture```s but the user code can provide another ```Executor```.
-When the ```Connection``` is submitted the root of the ```CompleteableFuture```
-network is completed triggering execution of the rest of the network.
diff --git a/java/AoJ/README.md b/java/AoJ/README.md
index b4205789..a2492e1a 100644
--- a/java/AoJ/README.md
+++ b/java/AoJ/README.md
@@ -1,56 +1,120 @@
-# AoJ: ADBA over JDBC
-
-ADBA is Asynchronous Database Access, a non-blocking database access api that Oracle is proposing as a Java standard. ADBA was announced at [JavaOne 2016](https://static.rainfocus.com/oracle/oow16/sess/1461693351182001EmRq/ppt/CONF1578%2020160916.pdf) and presented again at [JavaOne 2017](http://www.oracle.com/technetwork/database/application-development/jdbc/con1491-3961036.pdf). The ADBA source is available for download from the [OpenJDK sandbox](
-http://hg.openjdk.java.net/jdk/sandbox/file/9d3b0eb749a9/src/jdk.incubator.adba) as part of the OpenJDK project. You can get involved in the ADBA specification effort by following the [JDBC Expert Group mailing list](http://mail.openjdk.java.net/pipermail/jdbc-spec-discuss/).
-The ADBA Javadoc is [here](http://cr.openjdk.java.net/~lancea/8188051/apidoc/jdk.incubator.adba-summary.html)
-
-Reading a bunch of JavaDoc and interfaces can be interesting, but it is not nearly as engaging as having actual running code to play with. To that end, we have uploaded the beginnings of an implementation of ADBA running over standard JDBC, AoJ. AoJ is available for download from [GitHub](https://github.com/oracle/oracle-db-examples/tree/master/java/AoJ) under the Apache license. It should run with any reasonably standard compliant JDBC driver.
-
-AoJ implements only a small part of ADBA, but it is enough to write interesting code. It provides partial implementations of DataSourceFactory, DataSource, Connection, OperationGroup, RowOperation, CountOperation, Transaction and others. These implementations are not complete but there is enough there to write interesting database programs. The code that is there is untested, but it does work to some extent. The saving grace is that you can download the source and improve it: add new features, fix bugs, try out alternate implementations.
-
-Oracle is not proposing AoJ as an open source project. However, because AoJ is released under the Apache license, the Java community can fork the code and create a true open source project with this upload as a base. Oracle developers may contribute when we have time, but this would have to be a Java community effort.
-
-We could have held this code back and worked on it longer. Instead we thought it better to get it to the community as soon as we could. We hope that you agree.
-
-## Sample Code
-
-The following test case should give you some idea of what AoJ can do. It uses the scott/tiger [schema](https://github.com/oracle/dotnet-db-samples/blob/master/schemas/scott.sql). It should run with any JDBC driver connecting to a database with the scott schema.
-
-`````` public void transactionSample() {
- DataSourceFactory factory = DataSourceFactory.forName("com.oracle.adbaoverjdbc.DataSourceFactory");
- try (DataSource ds = factory.builder()
- .url(URL)
- .username(“scott")
- .password(“tiger")
- .build();
- Connection conn = ds.getConnection(t -> System.out.println("ERROR: " + t.getMessage()))) {
- Transaction trans = conn.transaction();
- CompletionStage idF = conn.rowOperation("select empno, ename from emp where ename = ? for update")
- .set("1", "CLARK", AdbaType.VARCHAR)
- .collect(Collector.of(
- () -> new int[1],
- (a, r) -> {a[0] = r.get("empno", Integer.class); },
- (l, r) -> null,
- a -> a[0])
- )
- .submit()
- .getCompletionStage();
- conn.countOperation("update emp set deptno = ? where empno = ?")
- .set("1", 50, AdbaType.INTEGER)
- .set("2", idF, AdbaType.INTEGER)
- .apply(c -> {
- if (c.getCount() != 1L) {
- trans.setRollbackOnly();
- throw new SqlException("updated wrong number of rows", null, null, -1, null, -1);
- }
- return c.getCount();
- })
- .onError(t -> t.printStackTrace())
- .submit();
- conn.catchErrors();
- conn.commitMaybeRollback(trans);
- }
- ForkJoinPool.commonPool().awaitQuiescence(1, TimeUnit.MINUTES);
- }
-
-
+# AoJ: ADBA over JDBC
+
+ADBA is Asynchronous Database Access, a non-blocking database access api that
+Oracle is proposing as a Java standard. ADBA was announced at
+[JavaOne 2016](https://static.rainfocus.com/oracle/oow16/sess/1461693351182001EmRq/ppt/CONF1578%2020160916.pdf)
+and presented again at [JavaOne 2017](http://www.oracle.com/technetwork/database/application-development/jdbc/con1491-3961036.pdf).
+The ADBA source is available for download from the [OpenJDK sandbox](http://hg.openjdk.java.net/jdk/sandbox/file/9d3b0eb749a9/src/jdk.incubator.adba)
+as part of the OpenJDK project and the JavaDoc is available [here](http://cr.openjdk.java.net/~lancea/8188051/apidoc/jdk.incubator.adba-summary.html).
+You can get involved in the ADBA specification effort by following the
+[JDBC Expert Group mailing list](http://mail.openjdk.java.net/pipermail/jdbc-spec-discuss/).
+
+Reading a bunch of JavaDoc and interfaces can be interesting, but it is not nearly
+as engaging as having actual running code to play with. To that end, we have
+uploaded the beginnings of an implementation of ADBA running over standard JDBC,
+AoJ. AoJ is available for download from [GitHub](https://github.com/oracle/oracle-db-examples/tree/master/java/AoJ)
+under the Apache license. It should run with any reasonably standard compliant
+JDBC driver.
+
+AoJ implements only a small part of ADBA, but it is enough to write interesting
+code. It provides partial implementations of ```DataSourceFactory```, ```DataSource```,
+```Connection```, ```OperationGroup```, ```RowOperation```, ```CountOperation```,
+```Transaction``` and others. These implementations are not complete but there is
+enough there to write interesting database programs. The code that is there is
+untested, but it does work to some extent. The saving grace is that you can
+download the source and improve it: add new features, fix bugs, try out alternate
+implementations.
+
+Oracle is not proposing AoJ as an open source project. However, because AoJ is
+released under the Apache license, the Java community can fork the code and create
+a true open source project with this upload as a base. Oracle developers may
+contribute when we have time, but this would have to be a Java community effort.
+
+We could have held this code back and worked on it longer. Instead we thought it
+better to get it to the community as soon as we could. We hope that you agree.
+
+## Building AoJ
+
+AoJ and ADBA require JDK 9 or later. Download ADBA from the
+[OpenJDK sandbox](http://hg.openjdk.java.net/jdk/sandbox/file/9d3b0eb749a9/src/jdk.incubator.adba).
+It does not have any dependencies outside of Java SE. Download AoJ from
+[GitHub](https://github.com/oracle/oracle-db-examples/tree/master/java/AoJ). Both
+are modularized so be sure to include the module-info.java files. AoJ depends on
+ADBA. The AoJ sample file depends on JUnit which is included with most IDEs but is
+also available [here](https://github.com/junit-team/junit4).
+
+To run the sample file you will need a SQL database and corresponding JDBC driver. AoJ
+has been run with [Oracle Database 12c](http://www.oracle.com/technetwork/database/enterprise-edition/downloads/index.html)
+and [Oracle Database 12c JDBC](http://www.oracle.com/technetwork/database/application-development/jdbc/downloads/index.html),
+but it should work with any reasonably standard compliant SQL database and JDBC
+driver. The sample file uses the scott/tiger schema available
+[here](https://github.com/oracle/dotnet-db-samples/blob/master/schemas/scott.sql).
+
+Start the database and load ```scott.sql```. Edit ```com.oracle.adbaoverjdbc.test.FirstLight.java```
+and set the constant ```URL``` to an appropriate value. AoJ will pass this value
+to ```java.sql.DriverManager.getConnection```. If you are using a database other
+than Oracle you should change the value of the constant ```TRIVIAL``` to some
+very trivial ```SELECT``` query.
+
+## Sample Code
+
+The following test case should give you some idea of what AoJ can do. It should
+run with any JDBC driver connecting to a database with the scott schema. This is
+the last test in ```com.oracle.adbaoverjdbc.test.FirstLight.java```. For an
+introduction to ADBA see the [JavaOne 2017 presentation](http://www.oracle.com/technetwork/database/application-development/jdbc/con1491-3961036.pdf).
+
+
+``` public void transactionSample() {
+ // get the AoJ DataSourceFactory
+ DataSourceFactory factory = DataSourceFactory.forName("com.oracle.adbaoverjdbc.DataSourceFactory");
+ // get a DataSource and a Connection
+ try (DataSource ds = factory.builder()
+ .url(URL)
+ .username(“scott")
+ .password(“tiger")
+ .build();
+ Connection conn = ds.getConnection(t -> System.out.println("ERROR: " + t.getMessage()))) {
+ // get a Transaction
+ Transaction trans = conn.transaction();
+ // select the EMPNO of CLARK
+ CompletionStage idF = conn.rowOperation("select empno, ename from emp where ename = ? for update")
+ .set("1", "CLARK", AdbaType.VARCHAR)
+ .collect(Collector.of(
+ () -> new int[1],
+ (a, r) -> {a[0] = r.get("empno", Integer.class); },
+ (l, r) -> null,
+ a -> a[0])
+ )
+ .submit()
+ .getCompletionStage();
+ // update CLARK to work in department 50
+ conn.countOperation("update emp set deptno = ? where empno = ?")
+ .set("1", 50, AdbaType.INTEGER)
+ .set("2", idF, AdbaType.INTEGER)
+ .apply(c -> {
+ if (c.getCount() != 1L) {
+ trans.setRollbackOnly();
+ throw new SqlException("updated wrong number of rows", null, null, -1, null, -1);
+ }
+ return c.getCount();
+ })
+ .onError(t -> t.printStackTrace())
+ .submit();
+
+ conn.catchErrors(); // resume normal execution if there were any errors
+ conn.commitMaybeRollback(trans); // commit (or rollback) the transaction
+ }
+ // wait for the async tasks to complete before exiting
+ ForkJoinPool.commonPool().awaitQuiescence(1, TimeUnit.MINUTES);
+ }```
+
+## AoJ Design Spec in 100 words or less
+
+The methods called by the user thread create a network
+([DAG](https://en.wikipedia.org/wiki/Directed_acyclic_graph)) of
+```CompletableFuture```s. These ```CompleteableFuture```s asynchronously execute
+the synchronous JDBC calls and the result processing code provided by the user
+code. By default AoJ uses ```ForkJoinPool.commonPool()``` to execute
+```CompletableFuture```s but the user code can provide another ```Executor```.
+When the ```Connection``` is submitted the root of the ```CompleteableFuture```
+network is completed triggering execution of the rest of the network.
From 9cc58ab8ead56dae96eac785718d4d3759e9d21a Mon Sep 17 00:00:00 2001
From: Kuassi Mensah
Date: Fri, 13 Apr 2018 09:25:50 -0700
Subject: [PATCH 10/92] Updated Readme.md
---
java/AoJ/README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/java/AoJ/README.md b/java/AoJ/README.md
index a2492e1a..18753998 100644
--- a/java/AoJ/README.md
+++ b/java/AoJ/README.md
@@ -30,7 +30,7 @@ released under the Apache license, the Java community can fork the code and crea
a true open source project with this upload as a base. Oracle developers may
contribute when we have time, but this would have to be a Java community effort.
-We could have held this code back and worked on it longer. Instead we thought it
+We could have held this code back and worked on it longer. Instead we thought it is
better to get it to the community as soon as we could. We hope that you agree.
## Building AoJ
From 77996cc748450a69a3cb8ddae3d7b2a999972a60 Mon Sep 17 00:00:00 2001
From: Kuassi Mensah
Date: Fri, 13 Apr 2018 09:29:06 -0700
Subject: [PATCH 11/92] Updated Readme.md
---
java/AoJ/README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/java/AoJ/README.md b/java/AoJ/README.md
index 18753998..436a309f 100644
--- a/java/AoJ/README.md
+++ b/java/AoJ/README.md
@@ -30,7 +30,7 @@ released under the Apache license, the Java community can fork the code and crea
a true open source project with this upload as a base. Oracle developers may
contribute when we have time, but this would have to be a Java community effort.
-We could have held this code back and worked on it longer. Instead we thought it is
+We could have held this code back and worked on it longer. Instead we thought it
better to get it to the community as soon as we could. We hope that you agree.
## Building AoJ
From 1aef548056e00759291b4a58b89a399922dea8c9 Mon Sep 17 00:00:00 2001
From: Kuassi Mensah
Date: Fri, 13 Apr 2018 09:32:55 -0700
Subject: [PATCH 12/92] Updated the Readme.md
---
java/AoJ/README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/java/AoJ/README.md b/java/AoJ/README.md
index 436a309f..a2492e1a 100644
--- a/java/AoJ/README.md
+++ b/java/AoJ/README.md
@@ -30,7 +30,7 @@ released under the Apache license, the Java community can fork the code and crea
a true open source project with this upload as a base. Oracle developers may
contribute when we have time, but this would have to be a Java community effort.
-We could have held this code back and worked on it longer. Instead we thought it
+We could have held this code back and worked on it longer. Instead we thought it
better to get it to the community as soon as we could. We hope that you agree.
## Building AoJ
From 8058676d2d7238963e22f9f75cf741d656fdabc4 Mon Sep 17 00:00:00 2001
From: Kuassi Mensah
Date: Fri, 13 Apr 2018 09:39:08 -0700
Subject: [PATCH 13/92] Readme.md
Chnages to Readme.md
---
java/AoJ/README.md | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/java/AoJ/README.md b/java/AoJ/README.md
index a2492e1a..ef3e413a 100644
--- a/java/AoJ/README.md
+++ b/java/AoJ/README.md
@@ -108,10 +108,11 @@ introduction to ADBA see the [JavaOne 2017 presentation](http://www.oracle.com/t
ForkJoinPool.commonPool().awaitQuiescence(1, TimeUnit.MINUTES);
}```
+
## AoJ Design Spec in 100 words or less
The methods called by the user thread create a network
-([DAG](https://en.wikipedia.org/wiki/Directed_acyclic_graph)) of
+(i.e., [DAG](https://en.wikipedia.org/wiki/Directed_acyclic_graph)) of
```CompletableFuture```s. These ```CompleteableFuture```s asynchronously execute
the synchronous JDBC calls and the result processing code provided by the user
code. By default AoJ uses ```ForkJoinPool.commonPool()``` to execute
From 6e445942b610fe6127deade20f59e946b2a529c5 Mon Sep 17 00:00:00 2001
From: Kuassi Mensah
Date: Fri, 13 Apr 2018 09:40:25 -0700
Subject: [PATCH 14/92] Formatting in Readme.md
---
java/AoJ/README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/java/AoJ/README.md b/java/AoJ/README.md
index ef3e413a..31006496 100644
--- a/java/AoJ/README.md
+++ b/java/AoJ/README.md
@@ -106,7 +106,7 @@ introduction to ADBA see the [JavaOne 2017 presentation](http://www.oracle.com/t
}
// wait for the async tasks to complete before exiting
ForkJoinPool.commonPool().awaitQuiescence(1, TimeUnit.MINUTES);
- }```
+ }
## AoJ Design Spec in 100 words or less
From b86d122aec09a02f38a0978fec3cae378bf09927 Mon Sep 17 00:00:00 2001
From: Kuassi Mensah
Date: Fri, 13 Apr 2018 09:41:42 -0700
Subject: [PATCH 15/92] Formatting in Readme.md
---
java/AoJ/README.md | 1 -
1 file changed, 1 deletion(-)
diff --git a/java/AoJ/README.md b/java/AoJ/README.md
index 31006496..5951983c 100644
--- a/java/AoJ/README.md
+++ b/java/AoJ/README.md
@@ -108,7 +108,6 @@ introduction to ADBA see the [JavaOne 2017 presentation](http://www.oracle.com/t
ForkJoinPool.commonPool().awaitQuiescence(1, TimeUnit.MINUTES);
}
-
## AoJ Design Spec in 100 words or less
The methods called by the user thread create a network
From 5e7d9278262feed0bdc8babecc0ee0408efed5a5 Mon Sep 17 00:00:00 2001
From: Kuassi Mensah
Date: Fri, 13 Apr 2018 09:42:28 -0700
Subject: [PATCH 16/92] Formatting
---
java/AoJ/README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/java/AoJ/README.md b/java/AoJ/README.md
index 5951983c..19e99438 100644
--- a/java/AoJ/README.md
+++ b/java/AoJ/README.md
@@ -106,7 +106,7 @@ introduction to ADBA see the [JavaOne 2017 presentation](http://www.oracle.com/t
}
// wait for the async tasks to complete before exiting
ForkJoinPool.commonPool().awaitQuiescence(1, TimeUnit.MINUTES);
- }
+ }'''
## AoJ Design Spec in 100 words or less
From 27fe2d795b93f5e0f0e4d8a60065ccd545fc5a68 Mon Sep 17 00:00:00 2001
From: Kuassi Mensah
Date: Fri, 13 Apr 2018 09:43:21 -0700
Subject: [PATCH 17/92] Formatting
---
java/AoJ/README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/java/AoJ/README.md b/java/AoJ/README.md
index 19e99438..58c193b5 100644
--- a/java/AoJ/README.md
+++ b/java/AoJ/README.md
@@ -106,7 +106,7 @@ introduction to ADBA see the [JavaOne 2017 presentation](http://www.oracle.com/t
}
// wait for the async tasks to complete before exiting
ForkJoinPool.commonPool().awaitQuiescence(1, TimeUnit.MINUTES);
- }'''
+ }``````
## AoJ Design Spec in 100 words or less
From 9cb5bccb83acfa4d199ffc9d6eea0e3b2ce7da47 Mon Sep 17 00:00:00 2001
From: Kuassi Mensah
Date: Fri, 13 Apr 2018 09:44:07 -0700
Subject: [PATCH 18/92] Fixed formattin typo
---
java/AoJ/README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/java/AoJ/README.md b/java/AoJ/README.md
index 58c193b5..9fe350c0 100644
--- a/java/AoJ/README.md
+++ b/java/AoJ/README.md
@@ -106,7 +106,7 @@ introduction to ADBA see the [JavaOne 2017 presentation](http://www.oracle.com/t
}
// wait for the async tasks to complete before exiting
ForkJoinPool.commonPool().awaitQuiescence(1, TimeUnit.MINUTES);
- }``````
+ }```
## AoJ Design Spec in 100 words or less
From f063b0e8129f781818b1ea9667b2c94a45c91660 Mon Sep 17 00:00:00 2001
From: Kuassi Mensah
Date: Fri, 13 Apr 2018 09:46:14 -0700
Subject: [PATCH 19/92] Formatting
---
java/AoJ/README.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/java/AoJ/README.md b/java/AoJ/README.md
index 9fe350c0..9d0abedc 100644
--- a/java/AoJ/README.md
+++ b/java/AoJ/README.md
@@ -107,6 +107,7 @@ introduction to ADBA see the [JavaOne 2017 presentation](http://www.oracle.com/t
// wait for the async tasks to complete before exiting
ForkJoinPool.commonPool().awaitQuiescence(1, TimeUnit.MINUTES);
}```
+
## AoJ Design Spec in 100 words or less
From 6b0015c77ee8c6b3029340a9961cfbe62db5d009 Mon Sep 17 00:00:00 2001
From: Kuassi Mensah
Date: Fri, 13 Apr 2018 09:47:14 -0700
Subject: [PATCH 20/92] Space
---
java/AoJ/README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/java/AoJ/README.md b/java/AoJ/README.md
index 9d0abedc..50af47c2 100644
--- a/java/AoJ/README.md
+++ b/java/AoJ/README.md
@@ -64,7 +64,7 @@ the last test in ```com.oracle.adbaoverjdbc.test.FirstLight.java```. For an
introduction to ADBA see the [JavaOne 2017 presentation](http://www.oracle.com/technetwork/database/application-development/jdbc/con1491-3961036.pdf).
-``` public void transactionSample() {
+```public void transactionSample() {
// get the AoJ DataSourceFactory
DataSourceFactory factory = DataSourceFactory.forName("com.oracle.adbaoverjdbc.DataSourceFactory");
// get a DataSource and a Connection
From 9c024b0766bda28b9734f863c0fbe93785a883be Mon Sep 17 00:00:00 2001
From: nigelbayliss
Date: Wed, 18 Apr 2018 17:14:19 +0100
Subject: [PATCH 21/92] tidy part0
---
optimizer/execution_plans/part0/eg1.lst | 19 +++
optimizer/execution_plans/part0/eg2.lst | 24 +++-
optimizer/execution_plans/part0/eg3.lst | 74 ++++++++--
optimizer/execution_plans/part0/eg4.lst | 36 ++++-
optimizer/execution_plans/part0/eg5.lst | 69 +++++++--
optimizer/execution_plans/part0/eg6.lst | 20 +++
.../execution_plans/part0/monitor_output.html | 135 +++++++++---------
optimizer/execution_plans/part0/plan.sql | 3 +
optimizer/execution_plans/part0/planp.sql | 3 +
optimizer/execution_plans/part0/stats.sql | 5 +-
10 files changed, 289 insertions(+), 99 deletions(-)
diff --git a/optimizer/execution_plans/part0/eg1.lst b/optimizer/execution_plans/part0/eg1.lst
index 9dd77db2..8cd2eaa4 100644
--- a/optimizer/execution_plans/part0/eg1.lst
+++ b/optimizer/execution_plans/part0/eg1.lst
@@ -1,9 +1,28 @@
SQL> @eg1
+SQL> column ename format a20
+SQL> column rname format a20
+SQL>
+SQL> select e.ename,r.rname
+ 2 from employees e
+ 3 join roles r on (r.id = e.role_id)
+ 4 join departments d on (d.id = e.dept_id)
+ 5 where e.staffno <= 10
+ 6 and d.dname in ('Department Name 1','Department Name 2');
ENAME RNAME
-------------------- --------------------
Employee Name 1 Role Name 1
+SQL>
+SQL> @plan
+SQL> --
+SQL> -- An example of retrieving a useful SQL Execution Plan
+SQL> --
+SQL> set linesize 220 tab off pagesize 1000 trims on
+SQL> column plan_table_output format a120
+SQL>
+SQL> SELECT *
+ 2 FROM table(DBMS_XPLAN.DISPLAY_CURSOR(FORMAT=>'ALL +OUTLINE'));
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------
diff --git a/optimizer/execution_plans/part0/eg2.lst b/optimizer/execution_plans/part0/eg2.lst
index 00fecf7e..2a032dd3 100644
--- a/optimizer/execution_plans/part0/eg2.lst
+++ b/optimizer/execution_plans/part0/eg2.lst
@@ -1,9 +1,29 @@
SQL> @eg2
+SQL> column ename format a20
+SQL> column rname format a20
+SQL>
+SQL> select /*+ gather_plan_statistics */
+ 2 e.ename,r.rname
+ 3 from employees e
+ 4 join roles r on (r.id = e.role_id)
+ 5 join departments d on (d.id = e.dept_id)
+ 6 where e.staffno <= 10
+ 7 and d.dname in ('Department Name 1','Department Name 2');
ENAME RNAME
-------------------- --------------------
Employee Name 1 Role Name 1
+SQL>
+SQL> @stats
+SQL> --
+SQL> -- Retrieving plan statistics and a useful plan
+SQL> --
+SQL> set linesize 210 tab off pagesize 1000 trims on
+SQL> column plan_table_output format a200
+SQL>
+SQL> SELECT *
+ 2 FROM table(DBMS_XPLAN.DISPLAY_CURSOR(FORMAT=>'ALLSTATS LAST ALL +OUTLINE'));
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@@ -20,8 +40,8 @@ Plan hash value: 2341252972
| Id | Operation | Name | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time | A-Rows | A-Time | Buffers | OMem | 1Mem | Used-Mem |
--------------------------------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | | 6 (100)| | 1 |00:00:00.01 | 28 | | | |
-|* 1 | HASH JOIN | | 1 | 3 | 192 | 6 (0)| 00:00:01 | 1 |00:00:00.01 | 28 | 1448K| 1448K| 535K (0)|
-|* 2 | HASH JOIN | | 1 | 3 | 147 | 4 (0)| 00:00:01 | 2 |00:00:00.01 | 17 | 2545K| 2545K| 804K (0)|
+|* 1 | HASH JOIN | | 1 | 3 | 192 | 6 (0)| 00:00:01 | 1 |00:00:00.01 | 28 | 1448K| 1448K| 533K (0)|
+|* 2 | HASH JOIN | | 1 | 3 | 147 | 4 (0)| 00:00:01 | 2 |00:00:00.01 | 17 | 2545K| 2545K| 768K (0)|
|* 3 | TABLE ACCESS FULL| DEPARTMENTS | 1 | 2 | 42 | 2 (0)| 00:00:01 | 2 |00:00:00.01 | 7 | | | |
|* 4 | TABLE ACCESS FULL| EMPLOYEES | 1 | 10 | 280 | 2 (0)| 00:00:01 | 10 |00:00:00.01 | 7 | | | |
| 5 | TABLE ACCESS FULL | ROLES | 1 | 20 | 300 | 2 (0)| 00:00:01 | 20 |00:00:00.01 | 8 | | | |
diff --git a/optimizer/execution_plans/part0/eg3.lst b/optimizer/execution_plans/part0/eg3.lst
index ea9664fc..63df6272 100644
--- a/optimizer/execution_plans/part0/eg3.lst
+++ b/optimizer/execution_plans/part0/eg3.lst
@@ -1,12 +1,55 @@
SQL> @eg3
+SQL> column ename format a20
+SQL> column rname format a20
+SQL>
+SQL> --
+SQL> -- Use this to capture a SQL_ID
+SQL> --
+SQL> var sqlid varchar2(100)
+SQL>
+SQL> --
+SQL> -- Long running queries will be monitored automatically
+SQL> -- so the hint won't always be required. In this case,
+SQL> -- it's over very quickly so I've added the hint.
+SQL> --
+SQL> select /*+ MONITOR */
+ 2 e.ename,r.rname
+ 3 from employees e
+ 4 join roles r on (r.id = e.role_id)
+ 5 join departments d on (d.id = e.dept_id)
+ 6 where e.staffno <= 10
+ 7 and d.dname in ('Department Name 1','Department Name 2');
ENAME RNAME
-------------------- --------------------
Employee Name 1 Role Name 1
+SQL>
+SQL> --
+SQL> -- Get the SQL_ID of the last SQL statement we ran
+SQL> --
+SQL> begin
+ 2 select prev_sql_id
+ 3 into :sqlid
+ 4 from v$session
+ 5 where sid=userenv('sid')
+ 6 and username is not null
+ 7 and prev_hash_value <> 0
+ 8 and rownum<2;
+ 9 end;
+ 10 /
PL/SQL procedure successfully completed.
+SQL>
+SQL> --
+SQL> -- Text first, then HTML
+SQL> --
+SQL> set long 100000 pagesize 0 linesize 250 tab off trims on
+SQL> column report format a230
+SQL>
+SQL> select DBMS_SQL_MONITOR.REPORT_SQL_MONITOR (sql_id=>:sqlid, report_level=>'all', type=>'text') report
+ 2 from dual;
SQL Monitoring Report
SQL Text
@@ -17,25 +60,25 @@ Global Information
------------------------------
Status : DONE (ALL ROWS)
Instance ID : 1
- Session : ADHOC (44:61676)
+ Session : ADHOC (26:20218)
SQL ID : an05rsj1up1k5
- SQL Execution ID : 16777228
- Execution Started : 03/16/2018 13:45:05
- First Refresh Time : 03/16/2018 13:45:05
- Last Refresh Time : 03/16/2018 13:45:05
- Duration : .001969s
+ SQL Execution ID : 16777229
+ Execution Started : 04/18/2018 17:11:00
+ First Refresh Time : 04/18/2018 17:11:00
+ Last Refresh Time : 04/18/2018 17:11:00
+ Duration : .003154s
Module/Action : SQL*Plus/-
Service : SYS$USERS
Program : sqlplus@prod12c (TNS V1-V3)
Fetch Calls : 2
Global Stats
-=======================================
-| Elapsed | Other | Fetch | Buffer |
-| Time(s) | Waits(s) | Calls | Gets |
-=======================================
-| 0.00 | 0.00 | 2 | 28 |
-=======================================
+=================================================
+| Elapsed | Cpu | Other | Fetch | Buffer |
+| Time(s) | Time(s) | Waits(s) | Calls | Gets |
+=================================================
+| 0.00 | 0.00 | 0.00 | 2 | 28 |
+=================================================
SQL Plan Monitoring Details (Plan Hash Value=2341252972)
==========================================================================================================================================
@@ -43,11 +86,14 @@ SQL Plan Monitoring Details (Plan Hash Value=2341252972)
| | | | (Estim) | | Active(s) | Active | | (Actual) | (Max) | (%) | (# samples) |
==========================================================================================================================================
| 0 | SELECT STATEMENT | | | | 1 | +0 | 1 | 1 | . | | |
-| 1 | HASH JOIN | | 3 | 6 | 1 | +0 | 1 | 1 | 523KB | | |
-| 2 | HASH JOIN | | 3 | 4 | 1 | +0 | 1 | 2 | 788KB | | |
+| 1 | HASH JOIN | | 3 | 6 | 1 | +0 | 1 | 1 | 533KB | | |
+| 2 | HASH JOIN | | 3 | 4 | 1 | +0 | 1 | 2 | 768KB | | |
| 3 | TABLE ACCESS FULL | DEPARTMENTS | 2 | 2 | 1 | +0 | 1 | 2 | . | | |
| 4 | TABLE ACCESS FULL | EMPLOYEES | 10 | 2 | 1 | +0 | 1 | 10 | . | | |
| 5 | TABLE ACCESS FULL | ROLES | 20 | 2 | 1 | +0 | 1 | 20 | . | | |
==========================================================================================================================================
+SQL>
+SQL> set termout off feedback off
+SQL> spool monitor_output.html
diff --git a/optimizer/execution_plans/part0/eg4.lst b/optimizer/execution_plans/part0/eg4.lst
index 9d4e4a70..7f1e3854 100644
--- a/optimizer/execution_plans/part0/eg4.lst
+++ b/optimizer/execution_plans/part0/eg4.lst
@@ -1,5 +1,38 @@
SQL> @eg4
+SQL> column ename format a20
+SQL> column rname format a20
+SQL>
+SQL> var sqlid varchar2(100)
+SQL>
+SQL> select /* MY_TEST_QUERY */
+ 2 e.ename,r.rname
+ 3 from employees e
+ 4 join roles r on (r.id = e.role_id)
+ 5 join departments d on (d.id = e.dept_id)
+ 6 where e.staffno <= 10
+ 7 and d.dname in ('Department Name 1','Department Name 2');
Employee Name 1 Role Name 1
+SQL>
+SQL> --
+SQL> -- In this example, let's search for the query
+SQL> -- in V$SQL. We could do this in another session
+SQL> -- while the query is executing.
+SQL> --
+SQL> begin
+ 2 select sql_id
+ 3 into :sqlid
+ 4 from v$sql
+ 5 where sql_text like '%MY_TEST_QUERY%'
+ 6 and sql_text not like '%v$sql%'
+ 7 and rownum<2;
+ 8 end;
+ 9 /
+SQL>
+SQL> set long 100000 pagesize 0 linesize 250 tab off trims on
+SQL> column plan_table_output format a230
+SQL>
+SQL> SELECT *
+ 2 FROM table(DBMS_XPLAN.DISPLAY_CURSOR(SQL_ID=>:sqlid,FORMAT=>'ALL +OUTLINE'));
SQL_ID fzfk7qqax6chk, child number 0
-------------------------------------
select /* MY_TEST_QUERY */ e.ename,r.rname from employees e
@@ -73,6 +106,5 @@ Column Projection Information (identified by operation id):
"E"."ROLE_ID"[NUMBER,22]
5 - (rowset=256) "R"."ID"[NUMBER,22], "R"."RNAME"[VARCHAR2,100]
-SQL> spoll off
-SP2-0042: unknown command "spoll off" - rest of line ignored.
+SQL>
SQL> spool off
diff --git a/optimizer/execution_plans/part0/eg5.lst b/optimizer/execution_plans/part0/eg5.lst
index 7f8a48ee..169ffe25 100644
--- a/optimizer/execution_plans/part0/eg5.lst
+++ b/optimizer/execution_plans/part0/eg5.lst
@@ -1,5 +1,45 @@
SQL> @eg5
+SQL> column ename format a20
+SQL> column rname format a20
+SQL>
+SQL> var sqlid varchar2(100)
+SQL>
+SQL> select /* MY_TEST_QUERY */ /*+ MONITOR */
+ 2 e.ename,r.rname
+ 3 from employees e
+ 4 join roles r on (r.id = e.role_id)
+ 5 join departments d on (d.id = e.dept_id)
+ 6 where e.staffno <= 10
+ 7 and d.dname in ('Department Name 1','Department Name 2');
Employee Name 1 Role Name 1
+SQL>
+SQL> --
+SQL> -- In this example, let's search for the query
+SQL> -- in V$SQL. We could do this in another session
+SQL> -- while the query is executing.
+SQL> --
+SQL> begin
+ 2 select sql_id
+ 3 into :sqlid
+ 4 from v$sql
+ 5 where sql_text like '%MY_TEST_QUERY%'
+ 6 and sql_text not like '%v$sql%'
+ 7 and rownum<2;
+ 8 end;
+ 9 /
+SQL>
+SQL> --
+SQL> -- Generate the SQL Monitor Report
+SQL> --
+SQL> -- If the test query was long-running, we could run this
+SQL> -- in a seperate SQL Plus session and watch the query's
+SQL> -- progress.
+SQL> --
+SQL> set long 100000 pagesize 0 linesize 250 tab off trims on
+SQL> column report format a230
+SQL>
+SQL> select DBMS_SQL_MONITOR.REPORT_SQL_MONITOR (sql_id=>:sqlid, report_level=>'all', type=>'text') report
+ 2 from dual;
SQL Monitoring Report
SQL Text
@@ -10,25 +50,25 @@ Global Information
------------------------------
Status : DONE (ALL ROWS)
Instance ID : 1
- Session : ADHOC (44:61676)
+ Session : ADHOC (26:20218)
SQL ID : 1j5mhvb79631d
- SQL Execution ID : 16777220
- Execution Started : 03/16/2018 13:45:23
- First Refresh Time : 03/16/2018 13:45:23
- Last Refresh Time : 03/16/2018 13:45:23
- Duration : .000591s
+ SQL Execution ID : 16777221
+ Execution Started : 04/18/2018 17:11:54
+ First Refresh Time : 04/18/2018 17:11:54
+ Last Refresh Time : 04/18/2018 17:11:54
+ Duration : .001999s
Module/Action : SQL*Plus/-
Service : SYS$USERS
Program : sqlplus@prod12c (TNS V1-V3)
Fetch Calls : 2
Global Stats
-=======================================
-| Elapsed | Other | Fetch | Buffer |
-| Time(s) | Waits(s) | Calls | Gets |
-=======================================
-| 0.00 | 0.00 | 2 | 28 |
-=======================================
+======================================
+| Elapsed | Cpu | Fetch | Buffer |
+| Time(s) | Time(s) | Calls | Gets |
+======================================
+| 0.00 | 0.00 | 2 | 28 |
+======================================
SQL Plan Monitoring Details (Plan Hash Value=2341252972)
==========================================================================================================================================
@@ -36,11 +76,12 @@ SQL Plan Monitoring Details (Plan Hash Value=2341252972)
| | | | (Estim) | | Active(s) | Active | | (Actual) | (Max) | (%) | (# samples) |
==========================================================================================================================================
| 0 | SELECT STATEMENT | | | | 1 | +0 | 1 | 1 | . | | |
-| 1 | HASH JOIN | | 3 | 6 | 1 | +0 | 1 | 1 | 545KB | | |
-| 2 | HASH JOIN | | 3 | 4 | 1 | +0 | 1 | 2 | 837KB | | |
+| 1 | HASH JOIN | | 3 | 6 | 1 | +0 | 1 | 1 | 534KB | | |
+| 2 | HASH JOIN | | 3 | 4 | 1 | +0 | 1 | 2 | 848KB | | |
| 3 | TABLE ACCESS FULL | DEPARTMENTS | 2 | 2 | 1 | +0 | 1 | 2 | . | | |
| 4 | TABLE ACCESS FULL | EMPLOYEES | 10 | 2 | 1 | +0 | 1 | 10 | . | | |
| 5 | TABLE ACCESS FULL | ROLES | 20 | 2 | 1 | +0 | 1 | 20 | . | | |
==========================================================================================================================================
+SQL>
SQL> spool off
diff --git a/optimizer/execution_plans/part0/eg6.lst b/optimizer/execution_plans/part0/eg6.lst
index 5f48bc17..08449010 100644
--- a/optimizer/execution_plans/part0/eg6.lst
+++ b/optimizer/execution_plans/part0/eg6.lst
@@ -1,5 +1,25 @@
SQL> @eg6
+SQL> column ename format a20
+SQL> column rname format a20
+SQL>
+SQL> select /*+ PARALLEL (e 2) */
+ 2 e.ename,r.rname
+ 3 from employees e
+ 4 join roles r on (r.id = e.role_id)
+ 5 join departments d on (d.id = e.dept_id)
+ 6 where e.staffno <= 10
+ 7 and d.dname in ('Department Name 1','Department Name 2');
Employee Name 1 Role Name 1
+SQL>
+SQL> @planp
+SQL> --
+SQL> -- Displaying a parallel SQL execution plan
+SQL> --
+SQL> set linesize 220 tab off pagesize 1000 trims on
+SQL> column plan_table_output format a120
+SQL>
+SQL> SELECT *
+ 2 FROM table(DBMS_XPLAN.DISPLAY_CURSOR(FORMAT=>'ALL +OUTLINE PARALLEL'));
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------
diff --git a/optimizer/execution_plans/part0/monitor_output.html b/optimizer/execution_plans/part0/monitor_output.html
index 0358ba71..940fba6e 100644
--- a/optimizer/execution_plans/part0/monitor_output.html
+++ b/optimizer/execution_plans/part0/monitor_output.html
@@ -1,3 +1,5 @@
+SQL> select DBMS_SQL_MONITOR.REPORT_SQL_MONITOR (sql_id=>:sqlid, report_level=>'all', type=>'active') report
+ 2 from dual;
@@ -19,76 +21,77 @@
+SQL> spool off
diff --git a/optimizer/execution_plans/part0/plan.sql b/optimizer/execution_plans/part0/plan.sql
index 6605385b..e757db9a 100644
--- a/optimizer/execution_plans/part0/plan.sql
+++ b/optimizer/execution_plans/part0/plan.sql
@@ -1,3 +1,6 @@
+--
+-- An example of retrieving a useful SQL Execution Plan
+--
set linesize 220 tab off pagesize 1000 trims on
column plan_table_output format a120
diff --git a/optimizer/execution_plans/part0/planp.sql b/optimizer/execution_plans/part0/planp.sql
index bbbdd5c8..e31aff09 100644
--- a/optimizer/execution_plans/part0/planp.sql
+++ b/optimizer/execution_plans/part0/planp.sql
@@ -1,3 +1,6 @@
+--
+-- Displaying a parallel SQL execution plan
+--
set linesize 220 tab off pagesize 1000 trims on
column plan_table_output format a120
diff --git a/optimizer/execution_plans/part0/stats.sql b/optimizer/execution_plans/part0/stats.sql
index f40cc255..d1e82a7f 100644
--- a/optimizer/execution_plans/part0/stats.sql
+++ b/optimizer/execution_plans/part0/stats.sql
@@ -1,5 +1,8 @@
+--
+-- Retrieving plan statistics and a useful plan
+--
set linesize 210 tab off pagesize 1000 trims on
column plan_table_output format a200
SELECT *
-FROM table(DBMS_XPLAN.DISPLAY_CURSOR(FORMAT=>'ALLSTATS LAST ADVANCED'));
+FROM table(DBMS_XPLAN.DISPLAY_CURSOR(FORMAT=>'ALLSTATS LAST ALL +OUTLINE'));
From 35bc6503e9e31fab0b2e9dc957911d7270c66763 Mon Sep 17 00:00:00 2001
From: Kuassi Mensah
Date: Mon, 23 Apr 2018 10:16:35 -0700
Subject: [PATCH 22/92] Changes to Connection.java, Operation.java and
OperationGroup.java
---
.../com/oracle/adbaoverjdbc/Connection.java | 10 ++++++++-
.../com/oracle/adbaoverjdbc/Operation.java | 22 ++++++++-----------
.../oracle/adbaoverjdbc/OperationGroup.java | 11 ++--------
3 files changed, 20 insertions(+), 23 deletions(-)
diff --git a/java/AoJ/src/com/oracle/adbaoverjdbc/com/oracle/adbaoverjdbc/Connection.java b/java/AoJ/src/com/oracle/adbaoverjdbc/com/oracle/adbaoverjdbc/Connection.java
index 6e803b73..342d821c 100644
--- a/java/AoJ/src/com/oracle/adbaoverjdbc/com/oracle/adbaoverjdbc/Connection.java
+++ b/java/AoJ/src/com/oracle/adbaoverjdbc/com/oracle/adbaoverjdbc/Connection.java
@@ -225,6 +225,12 @@ jdk.incubator.sql2.Submission
*
- * java DateTimeStampDemo -l -u
+ * java DateTimeStampSample -l -u
*
*/
import java.io.BufferedReader;
From 5c278c22a354303e3e4a33eb30367ec7802d13e4 Mon Sep 17 00:00:00 2001
From: Nirmala Sundarappa
Date: Fri, 27 Apr 2018 10:45:57 -0700
Subject: [PATCH 39/92] Update JSONBasicSample.java
---
java/jdbc/BasicSamples/JSONBasicSample.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/java/jdbc/BasicSamples/JSONBasicSample.java b/java/jdbc/BasicSamples/JSONBasicSample.java
index 1f697929..2b717e77 100755
--- a/java/jdbc/BasicSamples/JSONBasicSample.java
+++ b/java/jdbc/BasicSamples/JSONBasicSample.java
@@ -30,7 +30,7 @@
* console, and optionally specify the DB user and/or connect URL on
* the command-line. You can also modify these values in this file
* and recompile the code.
- * java JSONBasicDemo -l -u
+ * java JSONBasicSample -l -u
*/
import java.io.BufferedReader;
From 8bf115bc880b7d68b15fc8d61aaed40685962c53 Mon Sep 17 00:00:00 2001
From: Nirmala Sundarappa
Date: Fri, 27 Apr 2018 10:46:24 -0700
Subject: [PATCH 40/92] Update LobBasicSample.java
---
java/jdbc/BasicSamples/LobBasicSample.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/java/jdbc/BasicSamples/LobBasicSample.java b/java/jdbc/BasicSamples/LobBasicSample.java
index 5ae165b3..3f6cc87e 100755
--- a/java/jdbc/BasicSamples/LobBasicSample.java
+++ b/java/jdbc/BasicSamples/LobBasicSample.java
@@ -8,7 +8,7 @@
console, and optionally specify the DB user and/or connect URL on
the command-line. You can also modify these values in this file
and recompile the code.
- java LobBasic -l -u
+ java LobBasicSample -l -u
NOTES
Sample uses books.txt and books.png from current directory.
From bb79bd3fccbdb093c06a1118e10377b781e324b3 Mon Sep 17 00:00:00 2001
From: Nirmala Sundarappa
Date: Fri, 27 Apr 2018 10:46:41 -0700
Subject: [PATCH 41/92] Update PLSQLSample.java
---
java/jdbc/BasicSamples/PLSQLSample.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/java/jdbc/BasicSamples/PLSQLSample.java b/java/jdbc/BasicSamples/PLSQLSample.java
index d6892441..17015b65 100755
--- a/java/jdbc/BasicSamples/PLSQLSample.java
+++ b/java/jdbc/BasicSamples/PLSQLSample.java
@@ -18,7 +18,7 @@
* of user, password, and URL. This can be done by either updating
* this file directly or supplying the 3 values as command-line options
* and user input. The password is read from console or standard input.
- * java PLSQL2 -l -u
+ * java PLSQLSample -l -u
* If you do not update all the defaults, the program proceeds but
* will hit error when connecting.
*/
From 699ff6b609c88f2d3a13071a5c908176849133f5 Mon Sep 17 00:00:00 2001
From: Nirmala Sundarappa
Date: Fri, 27 Apr 2018 10:57:05 -0700
Subject: [PATCH 42/92] Update Readme.md
---
java/jdbc/BasicSamples/Readme.md | 25 +++++++++++++++++++++++--
1 file changed, 23 insertions(+), 2 deletions(-)
diff --git a/java/jdbc/BasicSamples/Readme.md b/java/jdbc/BasicSamples/Readme.md
index 66af33df..420565e2 100644
--- a/java/jdbc/BasicSamples/Readme.md
+++ b/java/jdbc/BasicSamples/Readme.md
@@ -30,7 +30,6 @@ and run the program.
(c) If you don't update the defaults, then the program proceeds with the defaults
but, will hit error when connecting as these are dummy values.
-----
## DateTimeStampSample.java:
This sample shows illustrates the usage of below Oracle column data types
DATE, TIMESTAMP, TIMESTAMP WITH TIME ZONE and TIMESTAMP WITH LOCAL TIME ZONE.
@@ -49,7 +48,29 @@ for Oracle Database 12c Release 2 (12.2).
This sample shows how to use different types of LOBs (Large Objects).
It shows using BLOB, CLOB, and NLOB as datatypes.
-##
+## PLSQLSample.java
+This sample demonstrates the usage of PL/SQL Stored Procedures and Functions in JDBC.
+
+## PreparedStatementBindingsSample.java
+This sample shows CRUD operations using the PreparedStatement with named bindings.
+
+## PreparedStatementSample.java
+This simple shows CRUD operations using the PreparedStatement object.
+
+## SQLXMLSample.java
+This sample shows how to create, insert, and query SQLXML values.
+
+ ## StatementSample.java
+ This sample shows CRUD operations using the Statement object.
+
+ ## UCPBasic.java
+ This sample shows simple steps of how JDBC applications use the Oracle Universal Connection Pool (UCP).
+
+ ## UCPLabeling.java
+ This sample shows how applications use the connection labeling feature of Oracle Universal Connection Pool (UCP).
+
+ ## UCPHarvesting.java
+
From bb2f75f8f93f79ec0be4f1e1a35ec4b640b3b885 Mon Sep 17 00:00:00 2001
From: Nirmala Sundarappa
Date: Fri, 27 Apr 2018 10:58:18 -0700
Subject: [PATCH 43/92] Update Readme.md
---
java/jdbc/BasicSamples/Readme.md | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/java/jdbc/BasicSamples/Readme.md b/java/jdbc/BasicSamples/Readme.md
index 420565e2..0bc4dbab 100644
--- a/java/jdbc/BasicSamples/Readme.md
+++ b/java/jdbc/BasicSamples/Readme.md
@@ -66,11 +66,14 @@ This sample shows how to create, insert, and query SQLXML values.
## UCPBasic.java
This sample shows simple steps of how JDBC applications use the Oracle Universal Connection Pool (UCP).
- ## UCPLabeling.java
- This sample shows how applications use the connection labeling feature of Oracle Universal Connection Pool (UCP).
-
- ## UCPHarvesting.java
+ ## UCPHarvesting.java
+ This code sample shows how applications use the connection harvesting feature of UCP.
+ ## UCPLabeling.java
+ This sample shows how applications use the connection labeling feature of UCP.
+
+ ##
+
From f2cf0123bf768d9de20338b54656beb7bd968b38 Mon Sep 17 00:00:00 2001
From: Nirmala Sundarappa
Date: Fri, 27 Apr 2018 10:59:27 -0700
Subject: [PATCH 44/92] Update Readme.md
---
java/jdbc/BasicSamples/Readme.md | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/java/jdbc/BasicSamples/Readme.md b/java/jdbc/BasicSamples/Readme.md
index 0bc4dbab..cb363d92 100644
--- a/java/jdbc/BasicSamples/Readme.md
+++ b/java/jdbc/BasicSamples/Readme.md
@@ -52,13 +52,13 @@ It shows using BLOB, CLOB, and NLOB as datatypes.
This sample demonstrates the usage of PL/SQL Stored Procedures and Functions in JDBC.
## PreparedStatementBindingsSample.java
-This sample shows CRUD operations using the PreparedStatement with named bindings.
+This sample shows CRUD operations using the ```PreparedStatement``` with named bindings.
## PreparedStatementSample.java
-This simple shows CRUD operations using the PreparedStatement object.
+This simple shows CRUD operations using the ```PreparedStatement``` object.
## SQLXMLSample.java
-This sample shows how to create, insert, and query SQLXML values.
+This sample shows how to create, insert, and query ``SQLXML`` values.
## StatementSample.java
This sample shows CRUD operations using the Statement object.
From 5c76f5eaeeb70c1374684e4e3a2e41d7b91c143e Mon Sep 17 00:00:00 2001
From: Nirmala Sundarappa
Date: Fri, 27 Apr 2018 11:05:12 -0700
Subject: [PATCH 45/92] Update Readme.md
---
java/jdbc/BasicSamples/Readme.md | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/java/jdbc/BasicSamples/Readme.md b/java/jdbc/BasicSamples/Readme.md
index cb363d92..84b89037 100644
--- a/java/jdbc/BasicSamples/Readme.md
+++ b/java/jdbc/BasicSamples/Readme.md
@@ -72,7 +72,14 @@ This sample shows how to create, insert, and query ``SQLXML`` values.
## UCPLabeling.java
This sample shows how applications use the connection labeling feature of UCP.
- ##
+ ## UCPManager.java
+ This sample shows how applications use UCP manager's administration functions.
+
+ ## UCPManagerMBean.java
+ This sample shows how applications use UCP manager MBean's administration functions.
+
+ ## UCPMaxConnReuse.java
+ This sample shows how applications use the MaxConnectionReuseTime and MaxConnectionReuseCount features of UCP.
From 53936869df8998590d919338f184096fe4bee226 Mon Sep 17 00:00:00 2001
From: Nirmala Sundarappa
Date: Fri, 27 Apr 2018 11:08:17 -0700
Subject: [PATCH 46/92] Update Readme.md
---
java/jdbc/BasicSamples/Readme.md | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/java/jdbc/BasicSamples/Readme.md b/java/jdbc/BasicSamples/Readme.md
index 84b89037..fcbe6f71 100644
--- a/java/jdbc/BasicSamples/Readme.md
+++ b/java/jdbc/BasicSamples/Readme.md
@@ -80,7 +80,12 @@ This sample shows how to create, insert, and query ``SQLXML`` values.
## UCPMaxConnReuse.java
This sample shows how applications use the MaxConnectionReuseTime and MaxConnectionReuseCount features of UCP.
-
+
+ ## UCPMultiUsers.java
+ This sample shows how JDBC applications use UCPP to pool connections for different users.
+
+ ## UCPTimeouts.java
+This sample shows key connection timeout features of UCP such as ConnectionWaitTimeout, InactiveConnectionTimeout, TimeToLiveConnectionTimeout, and AbandonedConnectionTimeout.
From 868ab0726590f42da9724b739e1ff2821a868b3b Mon Sep 17 00:00:00 2001
From: Nirmala Sundarappa
Date: Fri, 27 Apr 2018 11:09:04 -0700
Subject: [PATCH 47/92] Update UCPBasic.java
---
java/jdbc/BasicSamples/UCPBasic.java | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/java/jdbc/BasicSamples/UCPBasic.java b/java/jdbc/BasicSamples/UCPBasic.java
index 0786db42..9c388c2e 100755
--- a/java/jdbc/BasicSamples/UCPBasic.java
+++ b/java/jdbc/BasicSamples/UCPBasic.java
@@ -28,7 +28,7 @@
* for ALL 3 of user, password, and URL. This can be done by either updating
* this file directly or supplying the 3 values as command-line options
* and user input. The password is read from console or standard input.
- * java UCPBasic -url -user
+ * java UCPBasic -l -u
* If you do not update all the defaults, the program proceeds but
* will hit error when connecting.
*/
@@ -199,10 +199,10 @@ static void showError(String msg, Throwable exc) {
static void getRealUserPasswordUrl(String args[]) throws Exception {
// URL can be modified in file, or taken from command-line
- url = getOptionValue(args, "-url", DEFAULT_URL);
+ url = getOptionValue(args, "-l", DEFAULT_URL);
// DB user can be modified in file, or taken from command-line
- user = getOptionValue(args, "-user", DEFAULT_USER);
+ user = getOptionValue(args, "-u", DEFAULT_USER);
// DB user's password can be modified in file, or explicitly entered
readPassword(" Password for " + user + ": ");
From 926ce3f1bb593d63438482fbc4552665c7776eea Mon Sep 17 00:00:00 2001
From: Nirmala Sundarappa
Date: Fri, 27 Apr 2018 11:11:06 -0700
Subject: [PATCH 48/92] Update UCPHarvesting.java
---
java/jdbc/BasicSamples/UCPHarvesting.java | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/java/jdbc/BasicSamples/UCPHarvesting.java b/java/jdbc/BasicSamples/UCPHarvesting.java
index b8f8bbbc..c2d557d4 100755
--- a/java/jdbc/BasicSamples/UCPHarvesting.java
+++ b/java/jdbc/BasicSamples/UCPHarvesting.java
@@ -31,7 +31,7 @@
* for ALL 3 of user, password, and URL. This can be done by either updating
* this file directly or supplying the 3 values as command-line options
* and user input. The password is read from console or standard input.
- * java UCPHarvesting -url -user
+ * java UCPHarvesting -l -u
* If you do not update all the defaults, the program proceeds but
* will hit error when connecting.
*/
@@ -286,10 +286,10 @@ static void showError(String msg, Throwable exc) {
static void getRealUserPasswordUrl(String args[]) throws Exception {
// URL can be modified in file, or taken from command-line
- url = getOptionValue(args, "-url", DEFAULT_URL);
+ url = getOptionValue(args, "-l", DEFAULT_URL);
// DB user can be modified in file, or taken from command-line
- user = getOptionValue(args, "-user", DEFAULT_USER);
+ user = getOptionValue(args, "-u", DEFAULT_USER);
// DB user's password can be modified in file, or explicitly entered
readPassword(" Password for " + user + ": ");
From 65f9d8c63ece85d17b49ce860afa9137c946210c Mon Sep 17 00:00:00 2001
From: Nirmala Sundarappa
Date: Fri, 27 Apr 2018 11:11:43 -0700
Subject: [PATCH 49/92] Update UCPLabeling.java
---
java/jdbc/BasicSamples/UCPLabeling.java | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/java/jdbc/BasicSamples/UCPLabeling.java b/java/jdbc/BasicSamples/UCPLabeling.java
index c334b67e..f1808724 100755
--- a/java/jdbc/BasicSamples/UCPLabeling.java
+++ b/java/jdbc/BasicSamples/UCPLabeling.java
@@ -36,7 +36,7 @@
* for ALL 3 of user, password, and URL. This can be done by either updating
* this file directly or supplying the 3 values as command-line options
* and user input. The password is read from console or standard input.
- * java UCPLabeling -url -user
+ * java UCPLabeling -l -u
* If you do not update all the defaults, the program proceeds but
* will hit error when connecting.
*/
@@ -181,10 +181,10 @@ static void showError(String msg, Throwable exc) {
static void getRealUserPasswordUrl(String args[]) throws Exception {
// URL can be modified in file, or taken from command-line
- url = getOptionValue(args, "-url", DEFAULT_URL);
+ url = getOptionValue(args, "-l", DEFAULT_URL);
// DB user can be modified in file, or taken from command-line
- user = getOptionValue(args, "-user", DEFAULT_USER);
+ user = getOptionValue(args, "-u", DEFAULT_USER);
// DB user's password can be modified in file, or explicitly entered
readPassword(" Password for " + user + ": ");
From 0c8b165b767c29713e6e8c8aea028502a95a6b8d Mon Sep 17 00:00:00 2001
From: Nirmala Sundarappa
Date: Fri, 27 Apr 2018 11:12:17 -0700
Subject: [PATCH 50/92] Update UCPManager.java
---
java/jdbc/BasicSamples/UCPManager.java | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/java/jdbc/BasicSamples/UCPManager.java b/java/jdbc/BasicSamples/UCPManager.java
index 313f51a6..a1eefe6b 100755
--- a/java/jdbc/BasicSamples/UCPManager.java
+++ b/java/jdbc/BasicSamples/UCPManager.java
@@ -25,7 +25,7 @@
* for ALL 3 of user, password, and URL. This can be done by either updating
* this file directly or supplying the 3 values as command-line options
* and user input. The password is read from console or standard input.
- * java UCPManager -url -user
+ * java UCPManager -l -u
* If you do not update all the defaults, the program proceeds but
* will hit error when connecting.
*/
@@ -300,10 +300,10 @@ static void showError(String msg, Throwable exc) {
static void getRealUserPasswordUrl(String args[]) throws Exception {
// URL can be modified in file, or taken from command-line
- url = getOptionValue(args, "-url", DEFAULT_URL);
+ url = getOptionValue(args, "-l", DEFAULT_URL);
// DB user can be modified in file, or taken from command-line
- user = getOptionValue(args, "-user", DEFAULT_USER);
+ user = getOptionValue(args, "-u", DEFAULT_USER);
// DB user's password can be modified in file, or explicitly entered
readPassword(" Password for " + user + ": ");
From ddcd2426d5c15941cb6e40135afdc765968d34c3 Mon Sep 17 00:00:00 2001
From: Nirmala Sundarappa
Date: Fri, 27 Apr 2018 11:12:49 -0700
Subject: [PATCH 51/92] Update UCPManagerMBean.java
---
java/jdbc/BasicSamples/UCPManagerMBean.java | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/java/jdbc/BasicSamples/UCPManagerMBean.java b/java/jdbc/BasicSamples/UCPManagerMBean.java
index b6778658..c1d2a88c 100755
--- a/java/jdbc/BasicSamples/UCPManagerMBean.java
+++ b/java/jdbc/BasicSamples/UCPManagerMBean.java
@@ -23,7 +23,7 @@
* for ALL 3 of user, password, and URL. This can be done by either updating
* this file directly or supplying the 3 values as command-line options
* and user input. The password is read from console or standard input.
- * java UCPManagerMBean -url -user
+ * java UCPManagerMBean -l -u
* If you do not update all the defaults, the program proceeds but
* will hit error when connecting.
*/
@@ -319,10 +319,10 @@ static void showError(String msg, Throwable exc) {
static void getRealUserPasswordUrl(String args[]) throws Exception {
// URL can be modified in file, or taken from command-line
- url = getOptionValue(args, "-url", DEFAULT_URL);
+ url = getOptionValue(args, "-l", DEFAULT_URL);
// DB user can be modified in file, or taken from command-line
- user = getOptionValue(args, "-user", DEFAULT_USER);
+ user = getOptionValue(args, "-u", DEFAULT_USER);
// DB user's password can be modified in file, or explicitly entered
readPassword(" Password for " + user + ": ");
From 3ac7c68f6df05002b64588a52c90981bca448c19 Mon Sep 17 00:00:00 2001
From: Nirmala Sundarappa
Date: Fri, 27 Apr 2018 11:13:25 -0700
Subject: [PATCH 52/92] Update UCPMaxConnReuse.java
---
java/jdbc/BasicSamples/UCPMaxConnReuse.java | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/java/jdbc/BasicSamples/UCPMaxConnReuse.java b/java/jdbc/BasicSamples/UCPMaxConnReuse.java
index fca96b72..faf95c2b 100755
--- a/java/jdbc/BasicSamples/UCPMaxConnReuse.java
+++ b/java/jdbc/BasicSamples/UCPMaxConnReuse.java
@@ -37,7 +37,7 @@
* for ALL 3 of user, password, and URL. This can be done by either updating
* this file directly or supplying the 3 values as command-line options
* and user input. The password is read from console or standard input.
- * java UCPMaxConnReuse -url -user
+ * java UCPMaxConnReuse -l -u
* If you do not update all the defaults, the program proceeds but
* will hit error when connecting.
*/
@@ -259,10 +259,10 @@ static void showError(String msg, Throwable exc) {
static void getRealUserPasswordUrl(String args[]) throws Exception {
// URL can be modified in file, or taken from command-line
- url = getOptionValue(args, "-url", DEFAULT_URL);
+ url = getOptionValue(args, "-l", DEFAULT_URL);
// DB user can be modified in file, or taken from command-line
- user = getOptionValue(args, "-user", DEFAULT_USER);
+ user = getOptionValue(args, "-u", DEFAULT_USER);
// DB user's password can be modified in file, or explicitly entered
readPassword(" Password for " + user + ": ");
From a62033797ffa78a05d9d342390ea69ab4d416f8d Mon Sep 17 00:00:00 2001
From: Nirmala Sundarappa
Date: Fri, 27 Apr 2018 11:13:56 -0700
Subject: [PATCH 53/92] Update UCPMultiUsers.java
---
java/jdbc/BasicSamples/UCPMultiUsers.java | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/java/jdbc/BasicSamples/UCPMultiUsers.java b/java/jdbc/BasicSamples/UCPMultiUsers.java
index 9401712b..c4f72443 100755
--- a/java/jdbc/BasicSamples/UCPMultiUsers.java
+++ b/java/jdbc/BasicSamples/UCPMultiUsers.java
@@ -16,7 +16,7 @@
* for ALL 3 of user, password, and URL. This can be done by either updating
* this file directly or supplying the 3 values as command-line options
* and user input. The password is read from console or standard input.
- * java UCPMultiUsers -url -user
+ * java UCPMultiUsers -l -u
* If you do not update all the defaults, the program proceeds but
* will hit error when connecting.
*/
@@ -114,10 +114,10 @@ static void showError(String msg, Throwable exc) {
static void getRealUserPasswordUrl(String args[]) throws Exception {
// URL can be modified in file, or taken from command-line
- url = getOptionValue(args, "-url", DEFAULT_URL);
+ url = getOptionValue(args, "-l", DEFAULT_URL);
// DB user can be modified in file, or taken from command-line
- user = getOptionValue(args, "-user", DEFAULT_USER);
+ user = getOptionValue(args, "-u", DEFAULT_USER);
// DB user's password can be modified in file, or explicitly entered
readPassword(" Password for " + user + ": ");
From 93d2ed71eea6fa4ebb8b5d10ee99ab7ba3560ea4 Mon Sep 17 00:00:00 2001
From: Nirmala Sundarappa
Date: Fri, 27 Apr 2018 11:14:53 -0700
Subject: [PATCH 54/92] Update UCPTimeouts.java
---
java/jdbc/BasicSamples/UCPTimeouts.java | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/java/jdbc/BasicSamples/UCPTimeouts.java b/java/jdbc/BasicSamples/UCPTimeouts.java
index 030902ff..5bc1cc14 100755
--- a/java/jdbc/BasicSamples/UCPTimeouts.java
+++ b/java/jdbc/BasicSamples/UCPTimeouts.java
@@ -19,7 +19,7 @@
* for ALL 3 of user, password, and URL. This can be done by either updating
* this file directly or supplying the 3 values as command-line options
* and user input. The password is read from console or standard input.
- * java UCPTimeouts -url -user
+ * java UCPTimeouts -l -u
* If you do not update all the defaults, the program proceeds but
* will hit error when connecting.
*/
@@ -339,10 +339,10 @@ static void showError(String msg, Throwable exc) {
static void getRealUserPasswordUrl(String args[]) throws Exception {
// URL can be modified in file, or taken from command-line
- url = getOptionValue(args, "-url", DEFAULT_URL);
+ url = getOptionValue(args, "-l", DEFAULT_URL);
// DB user can be modified in file, or taken from command-line
- user = getOptionValue(args, "-user", DEFAULT_USER);
+ user = getOptionValue(args, "-u", DEFAULT_USER);
// DB user's password can be modified in file, or explicitly entered
readPassword(" Password for " + user + ": ");
From 40b17ec9eb6cb3da53378dcb7bb43366c3558998 Mon Sep 17 00:00:00 2001
From: Nirmala Sundarappa
Date: Fri, 27 Apr 2018 13:56:34 -0700
Subject: [PATCH 55/92] Update Readme.md
---
java/jdbc/BasicSamples/Readme.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/java/jdbc/BasicSamples/Readme.md b/java/jdbc/BasicSamples/Readme.md
index fcbe6f71..5abdb5b2 100644
--- a/java/jdbc/BasicSamples/Readme.md
+++ b/java/jdbc/BasicSamples/Readme.md
@@ -2,7 +2,7 @@
# Basic Samples in JDBC
"Basic Samples" is the first set of code samples aimed to show case some
-some of the basic operations and using some datatypes (LOB, SQLXML, DATE etc.,)
+of the basic operations and using some datatypes (LOB, SQLXML, DATE etc.,)
The samples also contain Universal Connection Pool (UCP) functionalities to show
how to harvest connections, label connections, how to use different timeouts, and
how to configure MBean to monitor UCP statistics etc., Read below for the
@@ -12,7 +12,7 @@ description of the code samples.
Before you run the code samples, we want you to create a new DB user and the necessary tables.
Download [SQLDeveloper](http://www.oracle.com/technetwork/developer-tools/sql-developer/downloads/sqldev-downloads-42-3802334.html) or you can use SQLPLUS. Connect to your database and login as SYSADMIN.
-Execute the script [JDBCSampleData.sql](https://github.com/oracle/oracle-db-examples/blob/basicsamples/java/jdbc/BasicSamples/JDBCSampleData.sql) that will create the new database user and the
+Execute the script [JDBCSampleData.sql](https://github.com/oracle/oracle-db-examples/blob/basicsamples/java/jdbc/BasicSamples/JDBCSampleData.sql) that will create the new database user (JDBCUSER) and the
tables necessary for the code samples.
# Running Code Samples
From 7b556a51adc794ac9e518074a0393a569a6bdf97 Mon Sep 17 00:00:00 2001
From: Nirmala Sundarappa
Date: Fri, 27 Apr 2018 13:57:51 -0700
Subject: [PATCH 56/92] Update Readme.md
---
java/jdbc/BasicSamples/Readme.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/java/jdbc/BasicSamples/Readme.md b/java/jdbc/BasicSamples/Readme.md
index 5abdb5b2..bee86415 100644
--- a/java/jdbc/BasicSamples/Readme.md
+++ b/java/jdbc/BasicSamples/Readme.md
@@ -12,7 +12,7 @@ description of the code samples.
Before you run the code samples, we want you to create a new DB user and the necessary tables.
Download [SQLDeveloper](http://www.oracle.com/technetwork/developer-tools/sql-developer/downloads/sqldev-downloads-42-3802334.html) or you can use SQLPLUS. Connect to your database and login as SYSADMIN.
-Execute the script [JDBCSampleData.sql](https://github.com/oracle/oracle-db-examples/blob/basicsamples/java/jdbc/BasicSamples/JDBCSampleData.sql) that will create the new database user (JDBCUSER) and the
+Execute the script [JDBCSampleData.sql](https://github.com/oracle/oracle-db-examples/blob/basicsamples/java/jdbc/BasicSamples/JDBCSampleData.sql) that will create the new database user (jdbcuser) and the
tables necessary for the code samples.
# Running Code Samples
From efb9172f252c8efcc867e38021a13ff3201f8171 Mon Sep 17 00:00:00 2001
From: Nirmala Sundarappa
Date: Fri, 27 Apr 2018 14:05:56 -0700
Subject: [PATCH 57/92] Update Readme.md
---
java/jdbc/BasicSamples/Readme.md | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/java/jdbc/BasicSamples/Readme.md b/java/jdbc/BasicSamples/Readme.md
index bee86415..7e4cee2f 100644
--- a/java/jdbc/BasicSamples/Readme.md
+++ b/java/jdbc/BasicSamples/Readme.md
@@ -1,12 +1,11 @@
# Basic Samples in JDBC
-"Basic Samples" is the first set of code samples aimed to show case some
+"Basic Samples" is the first set of code samples aimed to showcase some
of the basic operations and using some datatypes (LOB, SQLXML, DATE etc.,)
The samples also contain Universal Connection Pool (UCP) functionalities to show
how to harvest connections, label connections, how to use different timeouts, and
-how to configure MBean to monitor UCP statistics etc., Read below for the
-description of the code samples.
+how to configure MBean to monitor UCP statistics etc.,
# Creating DB User and Sample Data
Before you run the code samples, we want you to create a new DB user and the necessary tables.
@@ -16,20 +15,23 @@ Execute the script [JDBCSampleData.sql](https://github.com/oracle/oracle-db-exam
tables necessary for the code samples.
# Running Code Samples
-There are three ways to run the sample.
-(a) Run each sample by passing the database URL and database user as the command-line
+(a) Download the latest 12.2.0.1 ojdbc8.jar and ucp.jar and add these
+
+(b) Run each sample by passing the database URL and database user as the command-line
options. The password is read from console or standard input.
```java UCPMultiUsers -l -u ```
(b) Optionally, each sample has DEFAULT_URL, DEFAULT_USER, and DEFAULT_PASSWORD
in the file. You can choose to update these values with your database credentials
-and run the program.
-
-(c) If you don't update the defaults, then the program proceeds with the defaults
+and run the program. If you don't update the defaults, then the program proceeds with the defaults
but, will hit error when connecting as these are dummy values.
+```java UCPMultiUsers```
+
+Read below for the description of the code samples.
+
## DateTimeStampSample.java:
This sample shows illustrates the usage of below Oracle column data types
DATE, TIMESTAMP, TIMESTAMP WITH TIME ZONE and TIMESTAMP WITH LOCAL TIME ZONE.
From c12c2e858c3acf817a52bd507e22758627d6df32 Mon Sep 17 00:00:00 2001
From: Nirmala Sundarappa
Date: Fri, 27 Apr 2018 14:08:23 -0700
Subject: [PATCH 58/92] Update Readme.md
---
java/jdbc/BasicSamples/Readme.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/java/jdbc/BasicSamples/Readme.md b/java/jdbc/BasicSamples/Readme.md
index 7e4cee2f..cea076f4 100644
--- a/java/jdbc/BasicSamples/Readme.md
+++ b/java/jdbc/BasicSamples/Readme.md
@@ -16,7 +16,7 @@ tables necessary for the code samples.
# Running Code Samples
-(a) Download the latest 12.2.0.1 ojdbc8.jar and ucp.jar and add these
+(a) Download the [latest 12.2.0.1 ojdbc8.jar and ucp.jar](http://www.oracle.com/technetwork/database/features/jdbc/jdbc-ucp-122-3110062.html) and add these jars to the classpath.
(b) Run each sample by passing the database URL and database user as the command-line
options. The password is read from console or standard input.
From 7bbc254b9671e483d96e900b2342affaa379edc3 Mon Sep 17 00:00:00 2001
From: Nirmala Sundarappa
Date: Fri, 27 Apr 2018 14:14:23 -0700
Subject: [PATCH 59/92] Update Readme.md
---
java/jdbc/BasicSamples/Readme.md | 70 ++++++++------------------------
1 file changed, 17 insertions(+), 53 deletions(-)
diff --git a/java/jdbc/BasicSamples/Readme.md b/java/jdbc/BasicSamples/Readme.md
index cea076f4..70b6932e 100644
--- a/java/jdbc/BasicSamples/Readme.md
+++ b/java/jdbc/BasicSamples/Readme.md
@@ -32,62 +32,26 @@ but, will hit error when connecting as these are dummy values.
Read below for the description of the code samples.
-## DateTimeStampSample.java:
-This sample shows illustrates the usage of below Oracle column data types
+* **DateTimeStampSample.java**:This sample shows illustrates the usage of below Oracle column data types
DATE, TIMESTAMP, TIMESTAMP WITH TIME ZONE and TIMESTAMP WITH LOCAL TIME ZONE.
-It uses the table 'EMP_DATE_JDBC_SAMPLE' which has dates as columns for
-all the insert, delete, and update operations.
-
-## JDBCUrlSample.java
-This sample shows how to use the easy connection URL, connection URL with connection descriptors,
+* **JDBCUrlSample.java**:This sample shows how to use the easy connection URL, connection URL with connection descriptors,
and using TNS alias to connect to the Oracle database.
-
-## JSONBasicSample.java
-This sample shows how to use some of the enhancements in JavaScript Object Notation (JSON) support
+* **JSONBasicSample.java**: This sample shows how to use some of the enhancements in JavaScript Object Notation (JSON) support
for Oracle Database 12c Release 2 (12.2).
-
-## LobBasicSample.java
-This sample shows how to use different types of LOBs (Large Objects).
-It shows using BLOB, CLOB, and NLOB as datatypes.
-
-## PLSQLSample.java
-This sample demonstrates the usage of PL/SQL Stored Procedures and Functions in JDBC.
-
-## PreparedStatementBindingsSample.java
-This sample shows CRUD operations using the ```PreparedStatement``` with named bindings.
-
-## PreparedStatementSample.java
-This simple shows CRUD operations using the ```PreparedStatement``` object.
-
-## SQLXMLSample.java
-This sample shows how to create, insert, and query ``SQLXML`` values.
-
- ## StatementSample.java
- This sample shows CRUD operations using the Statement object.
-
- ## UCPBasic.java
- This sample shows simple steps of how JDBC applications use the Oracle Universal Connection Pool (UCP).
-
- ## UCPHarvesting.java
- This code sample shows how applications use the connection harvesting feature of UCP.
-
- ## UCPLabeling.java
- This sample shows how applications use the connection labeling feature of UCP.
-
- ## UCPManager.java
- This sample shows how applications use UCP manager's administration functions.
-
- ## UCPManagerMBean.java
- This sample shows how applications use UCP manager MBean's administration functions.
-
- ## UCPMaxConnReuse.java
- This sample shows how applications use the MaxConnectionReuseTime and MaxConnectionReuseCount features of UCP.
-
- ## UCPMultiUsers.java
- This sample shows how JDBC applications use UCPP to pool connections for different users.
-
- ## UCPTimeouts.java
-This sample shows key connection timeout features of UCP such as ConnectionWaitTimeout, InactiveConnectionTimeout, TimeToLiveConnectionTimeout, and AbandonedConnectionTimeout.
+* **LobBasicSample.java**: This sample shows how to use different types of LOBs (Large Objects). It shows using BLOB, CLOB, and NLOB as datatypes.
+* **PLSQLSample.java**: This sample demonstrates the usage of PL/SQL Stored Procedures and Functions in JDBC.
+* **PreparedStatementBindingsSample.java**: This sample shows CRUD operations using the ```PreparedStatement``` with named bindings.
+* **PreparedStatementSample.java**:This simple shows CRUD operations using the ```PreparedStatement``` object.
+* **SQLXMLSample.java**: This sample shows how to create, insert, and query ``SQLXML`` values.
+* **StatementSample.java**: This sample shows CRUD operations using the Statement object.
+* **UCPBasic.java**: This sample shows simple steps of how JDBC applications use the Oracle Universal Connection Pool (UCP).
+* **UCPHarvesting.java**: This code sample shows how applications use the connection harvesting feature of UCP.
+* **UCPLabeling.java**: This sample shows how applications use the connection labeling feature of UCP.
+* **UCPManager.java**: This sample shows how applications use UCP manager's administration functions.
+* **UCPManagerMBean.java**: This sample shows how applications use UCP manager MBean's administration functions.
+* **UCPMaxConnReuse.java**: This sample shows how applications use the MaxConnectionReuseTime and MaxConnectionReuseCount features of UCP.
+* **UCPMultiUsers.java**: This sample shows how JDBC applications use UCPP to pool connections for different users.
+* **UCPTimeouts.java**: This sample shows key connection timeout features of UCP such as ConnectionWaitTimeout, InactiveConnectionTimeout, TimeToLiveConnectionTimeout, and AbandonedConnectionTimeout.
From 287835a9d33cc417113fcb462313b7067b5bcfb2 Mon Sep 17 00:00:00 2001
From: Nirmala Sundarappa
Date: Fri, 27 Apr 2018 14:15:11 -0700
Subject: [PATCH 60/92] Update Readme.md
---
java/jdbc/BasicSamples/Readme.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/java/jdbc/BasicSamples/Readme.md b/java/jdbc/BasicSamples/Readme.md
index 70b6932e..41d6d5bb 100644
--- a/java/jdbc/BasicSamples/Readme.md
+++ b/java/jdbc/BasicSamples/Readme.md
@@ -30,7 +30,7 @@ but, will hit error when connecting as these are dummy values.
```java UCPMultiUsers```
-Read below for the description of the code samples.
+# Description of Code Samples
* **DateTimeStampSample.java**:This sample shows illustrates the usage of below Oracle column data types
DATE, TIMESTAMP, TIMESTAMP WITH TIME ZONE and TIMESTAMP WITH LOCAL TIME ZONE.
From 4740a12b5f03e3ec0042e794c83293995be3f4fa Mon Sep 17 00:00:00 2001
From: Nirmala Sundarappa
Date: Fri, 27 Apr 2018 14:17:48 -0700
Subject: [PATCH 61/92] Update Readme.md
---
java/jdbc/BasicSamples/Readme.md | 37 +++++++++++++++-----------------
1 file changed, 17 insertions(+), 20 deletions(-)
diff --git a/java/jdbc/BasicSamples/Readme.md b/java/jdbc/BasicSamples/Readme.md
index 41d6d5bb..c5faf5e0 100644
--- a/java/jdbc/BasicSamples/Readme.md
+++ b/java/jdbc/BasicSamples/Readme.md
@@ -32,26 +32,23 @@ but, will hit error when connecting as these are dummy values.
# Description of Code Samples
-* **DateTimeStampSample.java**:This sample shows illustrates the usage of below Oracle column data types
-DATE, TIMESTAMP, TIMESTAMP WITH TIME ZONE and TIMESTAMP WITH LOCAL TIME ZONE.
-* **JDBCUrlSample.java**:This sample shows how to use the easy connection URL, connection URL with connection descriptors,
-and using TNS alias to connect to the Oracle database.
-* **JSONBasicSample.java**: This sample shows how to use some of the enhancements in JavaScript Object Notation (JSON) support
-for Oracle Database 12c Release 2 (12.2).
-* **LobBasicSample.java**: This sample shows how to use different types of LOBs (Large Objects). It shows using BLOB, CLOB, and NLOB as datatypes.
-* **PLSQLSample.java**: This sample demonstrates the usage of PL/SQL Stored Procedures and Functions in JDBC.
-* **PreparedStatementBindingsSample.java**: This sample shows CRUD operations using the ```PreparedStatement``` with named bindings.
-* **PreparedStatementSample.java**:This simple shows CRUD operations using the ```PreparedStatement``` object.
-* **SQLXMLSample.java**: This sample shows how to create, insert, and query ``SQLXML`` values.
-* **StatementSample.java**: This sample shows CRUD operations using the Statement object.
-* **UCPBasic.java**: This sample shows simple steps of how JDBC applications use the Oracle Universal Connection Pool (UCP).
-* **UCPHarvesting.java**: This code sample shows how applications use the connection harvesting feature of UCP.
-* **UCPLabeling.java**: This sample shows how applications use the connection labeling feature of UCP.
-* **UCPManager.java**: This sample shows how applications use UCP manager's administration functions.
-* **UCPManagerMBean.java**: This sample shows how applications use UCP manager MBean's administration functions.
-* **UCPMaxConnReuse.java**: This sample shows how applications use the MaxConnectionReuseTime and MaxConnectionReuseCount features of UCP.
-* **UCPMultiUsers.java**: This sample shows how JDBC applications use UCPP to pool connections for different users.
-* **UCPTimeouts.java**: This sample shows key connection timeout features of UCP such as ConnectionWaitTimeout, InactiveConnectionTimeout, TimeToLiveConnectionTimeout, and AbandonedConnectionTimeout.
+* **DateTimeStampSample.java**:Shows the usage of Oracle column data types such as DATE, TIMESTAMP, TIMESTAMP WITH TIME ZONE and TIMESTAMP WITH LOCAL TIME ZONE.
+* **JDBCUrlSample.java**: Shows how to use the easy connection URL, connection URL with connection descriptors, and using TNS alias to connect to the Oracle database.
+* **JSONBasicSample.java**: Shows how to use some of the enhancements in JavaScript Object Notation (JSON) support for Oracle Database 12c Release 2 (12.2).
+* **LobBasicSample.java**: Shows how to use different types of LOBs (Large Objects). It shows using BLOB, CLOB, and NLOB as datatypes.
+* **PLSQLSample.java**: Demonstrates the usage of PL/SQL Stored Procedures and Functions in JDBC.
+* **PreparedStatementBindingsSample.java**: Shows CRUD operations using the ```PreparedStatement``` with named bindings.
+* **PreparedStatementSample.java**:Shows CRUD operations using the ```PreparedStatement``` object.
+* **SQLXMLSample.java**: Shows how to create, insert, and query ``SQLXML`` values.
+* **StatementSample.java**: Shows CRUD operations using the Statement object.
+* **UCPBasic.java**: Shows simple steps of how JDBC applications use the Oracle Universal Connection Pool (UCP).
+* **UCPHarvesting.java**: Shows how applications use the connection harvesting feature of UCP.
+* **UCPLabeling.java**: Shows how applications use the connection labeling feature of UCP.
+* **UCPManager.java**: Shows how applications use UCP manager's administration functions.
+* **UCPManagerMBean.java**: Shows how applications use UCP manager MBean's administration functions.
+* **UCPMaxConnReuse.java**: Shows how applications use the MaxConnectionReuseTime and MaxConnectionReuseCount features of UCP.
+* **UCPMultiUsers.java**: Shows how JDBC applications use UCPP to pool connections for different users.
+* **UCPTimeouts.java**: Shows key connection timeout features of UCP such as ConnectionWaitTimeout, InactiveConnectionTimeout, TimeToLiveConnectionTimeout, and AbandonedConnectionTimeout.
From 90c1e808259a5db656bc1c84f17f120bc68dbcc8 Mon Sep 17 00:00:00 2001
From: Nirmala Sundarappa
Date: Fri, 27 Apr 2018 14:18:21 -0700
Subject: [PATCH 62/92] Update Readme.md
---
java/jdbc/BasicSamples/Readme.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/java/jdbc/BasicSamples/Readme.md b/java/jdbc/BasicSamples/Readme.md
index c5faf5e0..2cc4bd1c 100644
--- a/java/jdbc/BasicSamples/Readme.md
+++ b/java/jdbc/BasicSamples/Readme.md
@@ -35,7 +35,7 @@ but, will hit error when connecting as these are dummy values.
* **DateTimeStampSample.java**:Shows the usage of Oracle column data types such as DATE, TIMESTAMP, TIMESTAMP WITH TIME ZONE and TIMESTAMP WITH LOCAL TIME ZONE.
* **JDBCUrlSample.java**: Shows how to use the easy connection URL, connection URL with connection descriptors, and using TNS alias to connect to the Oracle database.
* **JSONBasicSample.java**: Shows how to use some of the enhancements in JavaScript Object Notation (JSON) support for Oracle Database 12c Release 2 (12.2).
-* **LobBasicSample.java**: Shows how to use different types of LOBs (Large Objects). It shows using BLOB, CLOB, and NLOB as datatypes.
+* **LobBasicSample.java**: Shows how to use different types of LOBs (Large Objects), such as BLOB, CLOB, and NLOB as datatypes.
* **PLSQLSample.java**: Demonstrates the usage of PL/SQL Stored Procedures and Functions in JDBC.
* **PreparedStatementBindingsSample.java**: Shows CRUD operations using the ```PreparedStatement``` with named bindings.
* **PreparedStatementSample.java**:Shows CRUD operations using the ```PreparedStatement``` object.
From 06ac4c7d8ad1afbcf41fb8eb71363b27af790e8d Mon Sep 17 00:00:00 2001
From: Kuassi Mensah
Date: Tue, 1 May 2018 11:14:43 -0700
Subject: [PATCH 63/92] Changes to the Readme.md
Simplified Readme.
---
java/README.md | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/java/README.md b/java/README.md
index e056adeb..ef90579d 100644
--- a/java/README.md
+++ b/java/README.md
@@ -1,16 +1,16 @@
# Java based examples
-This is a repository of sample code that will demonstrate various concepts to assist Java developers in designing applications for accessing and processing data from the Oracle Database, leveraging Java Database Connectivity (JDBC), Universal Connection Pool (UCP); or running Java code directly in the database leveraging the embedded JVM (a.k.a. OJVM).
-
+This is a repository of sample code that will demonstrate various concepts to assist Java developers in designing applications for accessing and processing data in the Oracle Database, leveraging Java Database Connectivity (JDBC), Universal Connection Pool (UCP); or running Java code directly in the database leveraging the embedded JVM (a.k.a. OJVM).
We have just added the AoJ sub-repository for the Asynchronous Java Database Access (ADBA) over JDBC.
-# What's in Oracle database 12c Release 2 for Java Developers?
-* **Java 8**: Java 8 in JDBC/UCP and OJVM; JDBC 4.2
-* **Performance**: JIT (OJVM), Network Compression over WAN (JDBC), Configurable connection health check frequency (UCP), PL/SQL Callbace interface (JDBC)
-* **Scalability**: Shared Pool for Multi-Tenant Database (UCP), Shared Pool for Sharded database (UCP), Sharding Key APIs (JDBC, UCP), DRCP Proxy session sharing, DRCP support for multiple labels
-* **High-Availability**: Java APIs for FAN events (SimpleFan.jar), Planned Maintenance in the driver (JDBC), Application Continuity for XA Datasources, Transaction Guard for XA Datasource
-* **Security**: SSL v1.2 / TLS v 1.2 (JDBC)
-* **Manageability**: XMLconfiguration (UCP), Enable/disable/suspend/resume feature level logging (JDBC), MAX_THINK_TIME for Transactions in progress (DRCP), new statistics view and AWR reports
-* **Ease of Use** : Web Services Callout (OJCM), Long Identifiers (OJVM), PL/SQL Boolean (JDBC), Debugger for OJVM (Java Debug Wire Protocol)
+## JDBC
+Has the Basic Examaples for JDBC and The Universal Connection code samples.
+## OJVM
+Has code samples for Runnin Java in the database foreground process for in-place processing using the embedded JVM.
+
+## HRWebApp
+A complete end to end MVC application.
+
+## AoJ
+Has code samples for learning the Asynchronous Database Access over vanilla/synchrone JDBC. This is for functional testing only.
-# [White paper](http://bit.ly/2orH5jf)
# [See our OTN landing page for more information and resources](http://www.oracle.com/technetwork/database/application-development/java/overview/index.html)
From 3fdcc905471d83a8badf348dda0660a341c7623a Mon Sep 17 00:00:00 2001
From: Kuassi Mensah
Date: Wed, 2 May 2018 20:33:59 -0700
Subject: [PATCH 64/92] Sandbox URL
Up to date URL for the latest sandbox
---
java/AoJ/README.md | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/java/AoJ/README.md b/java/AoJ/README.md
index 50af47c2..1debc183 100644
--- a/java/AoJ/README.md
+++ b/java/AoJ/README.md
@@ -36,8 +36,14 @@ better to get it to the community as soon as we could. We hope that you agree.
## Building AoJ
AoJ and ADBA require JDK 9 or later. Download ADBA from the
-[OpenJDK sandbox](http://hg.openjdk.java.net/jdk/sandbox/file/9d3b0eb749a9/src/jdk.incubator.adba).
-It does not have any dependencies outside of Java SE. Download AoJ from
+[OpenJDK sandbox](http://hg.openjdk.java.net/jdk/sandbox/file/JDK-8188051-branch/src/jdk.incubator.adba/share/classes). It does not have any dependencies outside of Java SE.
+
+For building the API modules:
+$ mkdir -p mods/jdk.incubator.adba
+$ javac -d mods/jdk.incubator.adba/ $(find jdk.incubator.adba -name "*.java")
+$ jar --create --file=mlib/jdk.incubator.adba.jar --module-version=1.0 -C mods/jdk.incubator.adba/ .
+
+Download AoJ from
[GitHub](https://github.com/oracle/oracle-db-examples/tree/master/java/AoJ). Both
are modularized so be sure to include the module-info.java files. AoJ depends on
ADBA. The AoJ sample file depends on JUnit which is included with most IDEs but is
@@ -106,7 +112,7 @@ introduction to ADBA see the [JavaOne 2017 presentation](http://www.oracle.com/t
}
// wait for the async tasks to complete before exiting
ForkJoinPool.commonPool().awaitQuiescence(1, TimeUnit.MINUTES);
- }```
+ }````
## AoJ Design Spec in 100 words or less
From d93003d4ea6e3ee8d5d4a05507bb5eb5ec04c518 Mon Sep 17 00:00:00 2001
From: Kuassi Mensah
Date: Wed, 2 May 2018 20:38:26 -0700
Subject: [PATCH 65/92] Fixed command lines
Command lines for building the API
---
java/AoJ/README.md | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/java/AoJ/README.md b/java/AoJ/README.md
index 1debc183..db098c94 100644
--- a/java/AoJ/README.md
+++ b/java/AoJ/README.md
@@ -39,10 +39,11 @@ AoJ and ADBA require JDK 9 or later. Download ADBA from the
[OpenJDK sandbox](http://hg.openjdk.java.net/jdk/sandbox/file/JDK-8188051-branch/src/jdk.incubator.adba/share/classes). It does not have any dependencies outside of Java SE.
For building the API modules:
+```
$ mkdir -p mods/jdk.incubator.adba
$ javac -d mods/jdk.incubator.adba/ $(find jdk.incubator.adba -name "*.java")
$ jar --create --file=mlib/jdk.incubator.adba.jar --module-version=1.0 -C mods/jdk.incubator.adba/ .
-
+````
Download AoJ from
[GitHub](https://github.com/oracle/oracle-db-examples/tree/master/java/AoJ). Both
are modularized so be sure to include the module-info.java files. AoJ depends on
@@ -112,7 +113,7 @@ introduction to ADBA see the [JavaOne 2017 presentation](http://www.oracle.com/t
}
// wait for the async tasks to complete before exiting
ForkJoinPool.commonPool().awaitQuiescence(1, TimeUnit.MINUTES);
- }````
+ }
## AoJ Design Spec in 100 words or less
From 98bed61e2faa2c29000459b71735e6b6c5bd6123 Mon Sep 17 00:00:00 2001
From: Kuassi Mensah
Date: Wed, 2 May 2018 20:42:31 -0700
Subject: [PATCH 66/92] Page formatting
Page formating.
---
java/AoJ/README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/java/AoJ/README.md b/java/AoJ/README.md
index db098c94..369749e9 100644
--- a/java/AoJ/README.md
+++ b/java/AoJ/README.md
@@ -114,7 +114,7 @@ introduction to ADBA see the [JavaOne 2017 presentation](http://www.oracle.com/t
// wait for the async tasks to complete before exiting
ForkJoinPool.commonPool().awaitQuiescence(1, TimeUnit.MINUTES);
}
-
+```
## AoJ Design Spec in 100 words or less
From 9ba797397e6383a7aa79d7c9153f27ffa343b9ae Mon Sep 17 00:00:00 2001
From: Nirmala Sundarappa
Date: Thu, 3 May 2018 13:31:15 -0700
Subject: [PATCH 67/92] Update README.md
---
java/README.md | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/java/README.md b/java/README.md
index ef90579d..ebe0ff9c 100644
--- a/java/README.md
+++ b/java/README.md
@@ -3,14 +3,14 @@ This is a repository of sample code that will demonstrate various concepts to as
We have just added the AoJ sub-repository for the Asynchronous Java Database Access (ADBA) over JDBC.
## JDBC
-Has the Basic Examaples for JDBC and The Universal Connection code samples.
+Has the Basic Examples for JDBC and the Universal Connection code samples.
## OJVM
-Has code samples for Runnin Java in the database foreground process for in-place processing using the embedded JVM.
+Has code samples for Running Java in the database foreground process for in-place processing using the embedded JVM.
## HRWebApp
A complete end to end MVC application.
## AoJ
-Has code samples for learning the Asynchronous Database Access over vanilla/synchrone JDBC. This is for functional testing only.
+Has code samples for learning the Asynchronous Database Access over vanilla/synchronous JDBC. This is for functional testing only.
-# [See our OTN landing page for more information and resources](http://www.oracle.com/technetwork/database/application-development/java/overview/index.html)
+# [See our OTN landing page for more information and resources](http://www.oracle.com/technetwork/database/application-development/jdbc/overview/index.html)
From 9a12bd48462ec3b014220e8490b8dc044c2ef60b Mon Sep 17 00:00:00 2001
From: Nirmala Sundarappa
Date: Thu, 3 May 2018 13:32:26 -0700
Subject: [PATCH 68/92] Update README.md
---
java/README.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/java/README.md b/java/README.md
index ebe0ff9c..00639583 100644
--- a/java/README.md
+++ b/java/README.md
@@ -3,9 +3,9 @@ This is a repository of sample code that will demonstrate various concepts to as
We have just added the AoJ sub-repository for the Asynchronous Java Database Access (ADBA) over JDBC.
## JDBC
-Has the Basic Examples for JDBC and the Universal Connection code samples.
+Has the basic examples for JDBC and the Universal Connection Pool (UCP) code samples.
## OJVM
-Has code samples for Running Java in the database foreground process for in-place processing using the embedded JVM.
+Has code samples for running Java in the database foreground process for in-place processing using the embedded JVM.
## HRWebApp
A complete end to end MVC application.
From b408c0bde4d7e654bc6fba398b1570a96abaa686 Mon Sep 17 00:00:00 2001
From: Nirmala Sundarappa
Date: Sun, 6 May 2018 22:16:19 -0700
Subject: [PATCH 69/92] Rename the folder
---
.../DRCPSample.java | 0
.../DataSourceForJKS.java | 0
.../DataSourceSample.java | 0
.../InternalT2Driver.java | 0
.../InternalT2Driver.sql | 0
.../InternalT4Driver.java | 0
.../InternalT4Driver.sql | 0
.../ProxySessionSample.java | 0
.../ProxySessionSample.sql | 0
.../Readme.md | 0
java/jdbc/ConnectionSamples/UCPSample.java | 141 ++++++++++++++++++
.../build.xml | 0
12 files changed, 141 insertions(+)
rename java/jdbc/{ConnectionManagementSamples => ConnectionSamples}/DRCPSample.java (100%)
rename java/jdbc/{ConnectionManagementSamples => ConnectionSamples}/DataSourceForJKS.java (100%)
rename java/jdbc/{ConnectionManagementSamples => ConnectionSamples}/DataSourceSample.java (100%)
rename java/jdbc/{ConnectionManagementSamples => ConnectionSamples}/InternalT2Driver.java (100%)
rename java/jdbc/{ConnectionManagementSamples => ConnectionSamples}/InternalT2Driver.sql (100%)
rename java/jdbc/{ConnectionManagementSamples => ConnectionSamples}/InternalT4Driver.java (100%)
rename java/jdbc/{ConnectionManagementSamples => ConnectionSamples}/InternalT4Driver.sql (100%)
rename java/jdbc/{ConnectionManagementSamples => ConnectionSamples}/ProxySessionSample.java (100%)
rename java/jdbc/{ConnectionManagementSamples => ConnectionSamples}/ProxySessionSample.sql (100%)
rename java/jdbc/{ConnectionManagementSamples => ConnectionSamples}/Readme.md (100%)
create mode 100644 java/jdbc/ConnectionSamples/UCPSample.java
rename java/jdbc/{ConnectionManagementSamples => ConnectionSamples}/build.xml (100%)
diff --git a/java/jdbc/ConnectionManagementSamples/DRCPSample.java b/java/jdbc/ConnectionSamples/DRCPSample.java
similarity index 100%
rename from java/jdbc/ConnectionManagementSamples/DRCPSample.java
rename to java/jdbc/ConnectionSamples/DRCPSample.java
diff --git a/java/jdbc/ConnectionManagementSamples/DataSourceForJKS.java b/java/jdbc/ConnectionSamples/DataSourceForJKS.java
similarity index 100%
rename from java/jdbc/ConnectionManagementSamples/DataSourceForJKS.java
rename to java/jdbc/ConnectionSamples/DataSourceForJKS.java
diff --git a/java/jdbc/ConnectionManagementSamples/DataSourceSample.java b/java/jdbc/ConnectionSamples/DataSourceSample.java
similarity index 100%
rename from java/jdbc/ConnectionManagementSamples/DataSourceSample.java
rename to java/jdbc/ConnectionSamples/DataSourceSample.java
diff --git a/java/jdbc/ConnectionManagementSamples/InternalT2Driver.java b/java/jdbc/ConnectionSamples/InternalT2Driver.java
similarity index 100%
rename from java/jdbc/ConnectionManagementSamples/InternalT2Driver.java
rename to java/jdbc/ConnectionSamples/InternalT2Driver.java
diff --git a/java/jdbc/ConnectionManagementSamples/InternalT2Driver.sql b/java/jdbc/ConnectionSamples/InternalT2Driver.sql
similarity index 100%
rename from java/jdbc/ConnectionManagementSamples/InternalT2Driver.sql
rename to java/jdbc/ConnectionSamples/InternalT2Driver.sql
diff --git a/java/jdbc/ConnectionManagementSamples/InternalT4Driver.java b/java/jdbc/ConnectionSamples/InternalT4Driver.java
similarity index 100%
rename from java/jdbc/ConnectionManagementSamples/InternalT4Driver.java
rename to java/jdbc/ConnectionSamples/InternalT4Driver.java
diff --git a/java/jdbc/ConnectionManagementSamples/InternalT4Driver.sql b/java/jdbc/ConnectionSamples/InternalT4Driver.sql
similarity index 100%
rename from java/jdbc/ConnectionManagementSamples/InternalT4Driver.sql
rename to java/jdbc/ConnectionSamples/InternalT4Driver.sql
diff --git a/java/jdbc/ConnectionManagementSamples/ProxySessionSample.java b/java/jdbc/ConnectionSamples/ProxySessionSample.java
similarity index 100%
rename from java/jdbc/ConnectionManagementSamples/ProxySessionSample.java
rename to java/jdbc/ConnectionSamples/ProxySessionSample.java
diff --git a/java/jdbc/ConnectionManagementSamples/ProxySessionSample.sql b/java/jdbc/ConnectionSamples/ProxySessionSample.sql
similarity index 100%
rename from java/jdbc/ConnectionManagementSamples/ProxySessionSample.sql
rename to java/jdbc/ConnectionSamples/ProxySessionSample.sql
diff --git a/java/jdbc/ConnectionManagementSamples/Readme.md b/java/jdbc/ConnectionSamples/Readme.md
similarity index 100%
rename from java/jdbc/ConnectionManagementSamples/Readme.md
rename to java/jdbc/ConnectionSamples/Readme.md
diff --git a/java/jdbc/ConnectionSamples/UCPSample.java b/java/jdbc/ConnectionSamples/UCPSample.java
new file mode 100644
index 00000000..ff0a7f33
--- /dev/null
+++ b/java/jdbc/ConnectionSamples/UCPSample.java
@@ -0,0 +1,141 @@
+/* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.*/
+
+/*
+ DESCRIPTION
+ The code sample demonstrates Universal Connection Pool (UCP) as a client
+ side connection pool and does the following.
+ (a)Set the connection factory class name to
+ oracle.jdbc.pool.OracleDataSource before getting a connection.
+ (b)Set the driver connection properties(e.g.,defaultNChar,includeSynonyms).
+ (c)Set the connection pool properties(e.g.,minPoolSize, maxPoolSize).
+ (d)Get the connection and perform some database operations.
+
+ Step 1: Enter the Database details in DBConfig.properties file.
+ USER, PASSWORD, UCP_CONNFACTORY and URL are required.
+ Step 2: Run the sample with "ant UCPSample"
+
+ NOTES
+ Use JDK 1.7 and above
+
+ MODIFIED (MM/DD/YY)
+ nbsundar 02/13/15 - Creation (Contributor - tzhou)
+ */
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Properties;
+
+import oracle.ucp.jdbc.PoolDataSourceFactory;
+import oracle.ucp.jdbc.PoolDataSource;
+
+public class UCPSample {
+ final static String DB_URL="jdbc:oracle:thin:@myhost:1521/orclservicename";
+ final static String DB_USER = "hr";
+ final static String DB_PASSWORD = "hr";
+ final static String CONN_FACTORY_CLASS_NAME="oracle.jdbc.pool.OracleDataSource";
+
+ /*
+ * The sample demonstrates UCP as client side connection pool.
+ */
+ public static void main(String args[]) throws Exception {
+ // Get the PoolDataSource for UCP
+ PoolDataSource pds = PoolDataSourceFactory.getPoolDataSource();
+
+ // Set the connection factory first before all other properties
+ pds.setConnectionFactoryClassName(CONN_FACTORY_CLASS_NAME);
+ pds.setURL(DB_URL);
+ pds.setUser(DB_USER);
+ pds.setPassword(DB_PASSWORD);
+ pds.setConnectionPoolName("JDBC_UCP_POOL");
+
+ // Default is 0. Set the initial number of connections to be created
+ // when UCP is started.
+ pds.setInitialPoolSize(5);
+
+ // Default is 0. Set the minimum number of connections
+ // that is maintained by UCP at runtime.
+ pds.setMinPoolSize(5);
+
+ // Default is Integer.MAX_VALUE (2147483647). Set the maximum number of
+ // connections allowed on the connection pool.
+ pds.setMaxPoolSize(20);
+
+ // Default is 30secs. Set the frequency ineconds to enforce the timeout
+ // properties. Applies to inactiveConnectionTimeout(int secs),
+ // AbandonedConnectionTimeout(secs)& TimeToLiveConnectionTimeout(int secs).
+ // Range of valid values is 0 to Integer.MAX_VALUE. .
+ pds.setTimeoutCheckInterval(5);
+
+ // Default is 0. Set the maximum time, in seconds, that a
+ // connection remains available in the connection pool.
+ pds.setInactiveConnectionTimeout(10);
+
+ // Get the database connection from UCP.
+ try (Connection conn = pds.getConnection()) {
+ System.out.println("Available connections after checkout: "
+ + pds.getAvailableConnectionsCount());
+ System.out.println("Borrowed connections after checkout: "
+ + pds.getBorrowedConnectionsCount());
+ // Perform a database operation
+ doSQLWork(conn);
+ }
+ catch (SQLException e) {
+ System.out.println("UCPSample - " + "SQLException occurred : "
+ + e.getMessage());
+ }
+ System.out.println("Available connections after checkin: "
+ + pds.getAvailableConnectionsCount());
+ System.out.println("Borrowed connections after checkin: "
+ + pds.getBorrowedConnectionsCount());
+ }
+
+ /*
+ * Creates an EMP table and does an insert, update and select operations on
+ * the new table created.
+ */
+ public static void doSQLWork(Connection conn) {
+ try {
+ conn.setAutoCommit(false);
+ // Prepare a statement to execute the SQL Queries.
+ Statement statement = conn.createStatement();
+ // Create table EMP
+ statement.executeUpdate("create table EMP(EMPLOYEEID NUMBER,"
+ + "EMPLOYEENAME VARCHAR2 (20))");
+ System.out.println("New table EMP is created");
+ // Insert some records into the table EMP
+ statement.executeUpdate("insert into EMP values(1, 'Jennifer Jones')");
+ statement.executeUpdate("insert into EMP values(2, 'Alex Debouir')");
+ System.out.println("Two records are inserted.");
+
+ // Update a record on EMP table.
+ statement.executeUpdate("update EMP set EMPLOYEENAME='Alex Deborie'"
+ + " where EMPLOYEEID=2");
+ System.out.println("One record is updated.");
+
+ // Verify the table EMP
+ ResultSet resultSet = statement.executeQuery("select * from EMP");
+ System.out.println("\nNew table EMP contains:");
+ System.out.println("EMPLOYEEID" + " " + "EMPLOYEENAME");
+ System.out.println("--------------------------");
+ while (resultSet.next()) {
+ System.out.println(resultSet.getInt(1) + " " + resultSet.getString(2));
+ }
+ System.out.println("\nSuccessfully tested a connection from UCP");
+ }
+ catch (SQLException e) {
+ System.out.println("UCPSample - "
+ + "doSQLWork()- SQLException occurred : " + e.getMessage());
+ }
+ finally {
+ // Clean-up after everything
+ try (Statement statement = conn.createStatement()) {
+ statement.execute("drop table EMP");
+ }
+ catch (SQLException e) {
+ System.out.println("UCPSample - "
+ + "doSQLWork()- SQLException occurred : " + e.getMessage());
+ }
+ }
+ }
+}
diff --git a/java/jdbc/ConnectionManagementSamples/build.xml b/java/jdbc/ConnectionSamples/build.xml
similarity index 100%
rename from java/jdbc/ConnectionManagementSamples/build.xml
rename to java/jdbc/ConnectionSamples/build.xml
From 752098484fe4d382890a5fb5280e9a75ec8e86d1 Mon Sep 17 00:00:00 2001
From: nigelbayliss
Date: Wed, 9 May 2018 10:55:23 +0100
Subject: [PATCH 70/92] stats on load
---
optimizer/autonomous/stats_on_load/README.md | 1 +
optimizer/autonomous/stats_on_load/stat.sql | 11 +
.../autonomous/stats_on_load/test_load.lst | 925 ++++++++++++++++++
.../autonomous/stats_on_load/test_load.sql | 115 +++
optimizer/autonomous/stats_on_load/user.sql | 15 +
5 files changed, 1067 insertions(+)
create mode 100644 optimizer/autonomous/stats_on_load/README.md
create mode 100644 optimizer/autonomous/stats_on_load/stat.sql
create mode 100644 optimizer/autonomous/stats_on_load/test_load.lst
create mode 100644 optimizer/autonomous/stats_on_load/test_load.sql
create mode 100644 optimizer/autonomous/stats_on_load/user.sql
diff --git a/optimizer/autonomous/stats_on_load/README.md b/optimizer/autonomous/stats_on_load/README.md
new file mode 100644
index 00000000..8779a127
--- /dev/null
+++ b/optimizer/autonomous/stats_on_load/README.md
@@ -0,0 +1 @@
+This example demonstrates that statistics are maintained during direct path load.
diff --git a/optimizer/autonomous/stats_on_load/stat.sql b/optimizer/autonomous/stats_on_load/stat.sql
new file mode 100644
index 00000000..2b3bb36e
--- /dev/null
+++ b/optimizer/autonomous/stats_on_load/stat.sql
@@ -0,0 +1,11 @@
+select table_name,num_rows,sample_size,stale_stats from user_tab_statistics where table_name = 'FACT1';
+
+select table_name,column_name,low_value,high_value,sample_size,histogram from user_tab_col_statistics where table_name = 'FACT1';
+
+SELECT '<=' || endpoint_value AS range,
+ endpoint_value - (LAG(endpoint_value, 1, -1) OVER (ORDER BY endpoint_value)+1) + 1 AS vals_in_range,
+ endpoint_number - LAG(endpoint_number, 1, 0) OVER (ORDER BY endpoint_value) AS frequency
+FROM user_tab_histograms
+WHERE table_name = 'FACT1'
+AND column_name = 'NUM1'
+ORDER BY endpoint_value;
diff --git a/optimizer/autonomous/stats_on_load/test_load.lst b/optimizer/autonomous/stats_on_load/test_load.lst
new file mode 100644
index 00000000..dbb82c0d
--- /dev/null
+++ b/optimizer/autonomous/stats_on_load/test_load.lst
@@ -0,0 +1,925 @@
+SQL>
+SQL> drop table fact1 purge;
+
+Error starting at line : 18 File @ /u01/npb/Features/GIT2/oracle-db-examples/optimizer/autonomous/stats_on_load/test_load.sql
+In command -
+drop table fact1 purge
+Error report -
+ORA-00942: table or view does not exist
+
+Elapsed: 00:00:00.393
+SQL> drop table fact1_source purge;
+
+Error starting at line : 19 File @ /u01/npb/Features/GIT2/oracle-db-examples/optimizer/autonomous/stats_on_load/test_load.sql
+In command -
+drop table fact1_source purge
+Error report -
+ORA-00942: table or view does not exist
+
+Elapsed: 00:00:00.200
+SQL>
+SQL> create table fact1 (num0 number(10), num1 number(10), txt1 varchar2(100));
+
+Table FACT1 created.
+
+Elapsed: 00:00:00.103
+SQL>
+SQL> create table fact1_source as
+ 2 select * from fact1 where 1=-1;
+
+Table FACT1_SOURCE created.
+
+Elapsed: 00:00:00.116
+SQL>
+SQL> insert /*+ APPEND */ into fact1_source
+ 2 select rownum,mod(rownum,10),'XXX'||rownum
+ 3 from dual connect by rownum <= 10000;
+
+10,000 rows inserted.
+
+Elapsed: 00:00:00.457
+SQL>
+SQL> commit;
+
+Commit complete.
+
+Elapsed: 00:00:00.094
+SQL>
+SQL> --
+SQL> -- Notice that NUM_ROWS is maintained - we have stats on initial load
+SQL> --
+SQL> select table_name,num_rows from user_tables where table_name = 'FACT1_SOURCE';
+
+TABLE_NAME NUM_ROWS
+------------------------------ ----------
+FACT1_SOURCE 10000
+
+Elapsed: 00:00:00.480
+SQL>
+SQL> pause p...
+p...
+
+SQL>
+SQL> --
+SQL> -- Insert more rows into FACT1
+SQL> --
+SQL> insert /*+ APPEND */ into fact1 select num0,1,txt1 from fact1_source;
+
+10,000 rows inserted.
+
+Elapsed: 00:00:00.319
+SQL> commit;
+
+Commit complete.
+
+Elapsed: 00:00:00.094
+SQL> @stat
+SQL> select table_name,num_rows,sample_size,stale_stats from user_tab_statistics where table_name = 'FACT1';
+
+TABLE_NAME NUM_ROWS SAMPLE_SIZE STA
+------------------------------ ---------- ----------- ---
+FACT1 10000 10000 NO
+
+Elapsed: 00:00:00.119
+SQL>
+SQL> select table_name,column_name,low_value,high_value,sample_size,histogram from user_tab_col_statistics where table_name = 'FACT1';
+
+TABLE_NAME COLUMN_NAME LOW_VALUE HIGH_VALUE SAMPLE_SIZE HISTOGRAM
+------------------------------ ------------------------------ ------------------------------ ------------------------------ ----------- ---------------
+FACT1 NUM0 C102 C302 10000 HYBRID
+FACT1 NUM1 C102 C102 10000 FREQUENCY
+FACT1 TXT1 58585831 58585839393939 10000 HYBRID
+
+Elapsed: 00:00:00.135
+SQL>
+SQL> SELECT '<=' || endpoint_value AS range,
+ 2 endpoint_value - (LAG(endpoint_value, 1, -1) OVER (ORDER BY endpoint_value)+1) + 1 AS vals_in_range,
+ 3 endpoint_number - LAG(endpoint_number, 1, 0) OVER (ORDER BY endpoint_value) AS frequency
+ 4 FROM user_tab_histograms
+ 5 WHERE table_name = 'FACT1'
+ 6 AND column_name = 'NUM1'
+ 7 ORDER BY endpoint_value;
+
+RANGE VALS_IN_RANGE FREQUENCY
+---------- ------------- ----------
+<=1 2 5500
+
+Elapsed: 00:00:00.096
+Elapsed: 00:00:00.097
+SQL>
+SQL> -- Notice above that statistics are still maintained
+SQL> -- even though FACT1 was not empty before
+SQL> -- the INSERT. The histograms are maintained too.
+SQL> pause p...
+p...
+
+SQL>
+SQL> insert /*+ APPEND */ into fact1 select num0,2,txt1 from fact1_source;
+
+10,000 rows inserted.
+
+Elapsed: 00:00:00.423
+SQL> commit;
+
+Commit complete.
+
+Elapsed: 00:00:00.094
+SQL> @stat
+SQL> select table_name,num_rows,sample_size,stale_stats from user_tab_statistics where table_name = 'FACT1';
+
+TABLE_NAME NUM_ROWS SAMPLE_SIZE STA
+------------------------------ ---------- ----------- ---
+FACT1 20000 20000 NO
+
+Elapsed: 00:00:00.148
+SQL>
+SQL> select table_name,column_name,low_value,high_value,sample_size,histogram from user_tab_col_statistics where table_name = 'FACT1';
+
+TABLE_NAME COLUMN_NAME LOW_VALUE HIGH_VALUE SAMPLE_SIZE HISTOGRAM
+------------------------------ ------------------------------ ------------------------------ ------------------------------ ----------- ---------------
+FACT1 NUM0 C102 C302 20000 HYBRID
+FACT1 NUM1 C102 C103 20000 FREQUENCY
+FACT1 TXT1 58585831 58585839393939 20000 HYBRID
+
+Elapsed: 00:00:00.105
+SQL>
+SQL> SELECT '<=' || endpoint_value AS range,
+ 2 endpoint_value - (LAG(endpoint_value, 1, -1) OVER (ORDER BY endpoint_value)+1) + 1 AS vals_in_range,
+ 3 endpoint_number - LAG(endpoint_number, 1, 0) OVER (ORDER BY endpoint_value) AS frequency
+ 4 FROM user_tab_histograms
+ 5 WHERE table_name = 'FACT1'
+ 6 AND column_name = 'NUM1'
+ 7 ORDER BY endpoint_value;
+
+RANGE VALS_IN_RANGE FREQUENCY
+---------- ------------- ----------
+<=1 2 10000
+<=2 1 10000
+
+Elapsed: 00:00:00.096
+Elapsed: 00:00:00.096
+SQL>
+SQL> -- Notice again - statistics are still maintained
+SQL> -- even though FACT1 was not empty before
+SQL> -- the INSERT. The histograms continue to be maintained.
+SQL> pause p...
+p...
+
+SQL>
+SQL> insert /*+ APPEND */ into fact1 select num0,3,txt1 from fact1_source;
+
+10,000 rows inserted.
+
+Elapsed: 00:00:00.421
+SQL> commit;
+
+Commit complete.
+
+Elapsed: 00:00:00.099
+SQL> @stat
+SQL> select table_name,num_rows,sample_size,stale_stats from user_tab_statistics where table_name = 'FACT1';
+
+TABLE_NAME NUM_ROWS SAMPLE_SIZE STA
+------------------------------ ---------- ----------- ---
+FACT1 30000 30000 NO
+
+Elapsed: 00:00:00.101
+SQL>
+SQL> select table_name,column_name,low_value,high_value,sample_size,histogram from user_tab_col_statistics where table_name = 'FACT1';
+
+TABLE_NAME COLUMN_NAME LOW_VALUE HIGH_VALUE SAMPLE_SIZE HISTOGRAM
+------------------------------ ------------------------------ ------------------------------ ------------------------------ ----------- ---------------
+FACT1 NUM0 C102 C302 30000 HYBRID
+FACT1 NUM1 C102 C104 30000 FREQUENCY
+FACT1 TXT1 58585831 58585839393939 30000 HYBRID
+
+Elapsed: 00:00:00.110
+SQL>
+SQL> SELECT '<=' || endpoint_value AS range,
+ 2 endpoint_value - (LAG(endpoint_value, 1, -1) OVER (ORDER BY endpoint_value)+1) + 1 AS vals_in_range,
+ 3 endpoint_number - LAG(endpoint_number, 1, 0) OVER (ORDER BY endpoint_value) AS frequency
+ 4 FROM user_tab_histograms
+ 5 WHERE table_name = 'FACT1'
+ 6 AND column_name = 'NUM1'
+ 7 ORDER BY endpoint_value;
+
+RANGE VALS_IN_RANGE FREQUENCY
+---------- ------------- ----------
+<=1 2 10000
+<=2 1 10000
+<=3 1 10000
+
+Elapsed: 00:00:00.104
+Elapsed: 00:00:00.105
+SQL>
+SQL> insert /*+ APPEND */ into fact1 select num0,4,txt1 from fact1_source;
+
+10,000 rows inserted.
+
+Elapsed: 00:00:00.389
+SQL> commit;
+
+Commit complete.
+
+Elapsed: 00:00:00.100
+SQL> @stat
+SQL> select table_name,num_rows,sample_size,stale_stats from user_tab_statistics where table_name = 'FACT1';
+
+TABLE_NAME NUM_ROWS SAMPLE_SIZE STA
+------------------------------ ---------- ----------- ---
+FACT1 40000 40000 NO
+
+Elapsed: 00:00:00.095
+SQL>
+SQL> select table_name,column_name,low_value,high_value,sample_size,histogram from user_tab_col_statistics where table_name = 'FACT1';
+
+TABLE_NAME COLUMN_NAME LOW_VALUE HIGH_VALUE SAMPLE_SIZE HISTOGRAM
+------------------------------ ------------------------------ ------------------------------ ------------------------------ ----------- ---------------
+FACT1 NUM0 C102 C302 40000 HYBRID
+FACT1 NUM1 C102 C105 40000 FREQUENCY
+FACT1 TXT1 58585831 58585839393939 40000 HYBRID
+
+Elapsed: 00:00:00.120
+SQL>
+SQL> SELECT '<=' || endpoint_value AS range,
+ 2 endpoint_value - (LAG(endpoint_value, 1, -1) OVER (ORDER BY endpoint_value)+1) + 1 AS vals_in_range,
+ 3 endpoint_number - LAG(endpoint_number, 1, 0) OVER (ORDER BY endpoint_value) AS frequency
+ 4 FROM user_tab_histograms
+ 5 WHERE table_name = 'FACT1'
+ 6 AND column_name = 'NUM1'
+ 7 ORDER BY endpoint_value;
+
+RANGE VALS_IN_RANGE FREQUENCY
+---------- ------------- ----------
+<=1 2 10000
+<=2 1 10000
+<=3 1 10000
+<=4 1 10000
+
+Elapsed: 00:00:00.107
+Elapsed: 00:00:00.107
+SQL>
+SQL> insert /*+ APPEND */ into fact1 select num0,5,txt1 from fact1;
+
+40,000 rows inserted.
+
+Elapsed: 00:00:00.434
+SQL> commit;
+
+Commit complete.
+
+Elapsed: 00:00:00.095
+SQL> @stat
+SQL> select table_name,num_rows,sample_size,stale_stats from user_tab_statistics where table_name = 'FACT1';
+
+TABLE_NAME NUM_ROWS SAMPLE_SIZE STA
+------------------------------ ---------- ----------- ---
+FACT1 80000 80000 NO
+
+Elapsed: 00:00:00.103
+SQL>
+SQL> select table_name,column_name,low_value,high_value,sample_size,histogram from user_tab_col_statistics where table_name = 'FACT1';
+
+TABLE_NAME COLUMN_NAME LOW_VALUE HIGH_VALUE SAMPLE_SIZE HISTOGRAM
+------------------------------ ------------------------------ ------------------------------ ------------------------------ ----------- ---------------
+FACT1 NUM0 C102 C302 80000 HYBRID
+FACT1 NUM1 C102 C106 80000 FREQUENCY
+FACT1 TXT1 58585831 58585839393939 80000 HYBRID
+
+Elapsed: 00:00:00.107
+SQL>
+SQL> SELECT '<=' || endpoint_value AS range,
+ 2 endpoint_value - (LAG(endpoint_value, 1, -1) OVER (ORDER BY endpoint_value)+1) + 1 AS vals_in_range,
+ 3 endpoint_number - LAG(endpoint_number, 1, 0) OVER (ORDER BY endpoint_value) AS frequency
+ 4 FROM user_tab_histograms
+ 5 WHERE table_name = 'FACT1'
+ 6 AND column_name = 'NUM1'
+ 7 ORDER BY endpoint_value;
+
+RANGE VALS_IN_RANGE FREQUENCY
+---------- ------------- ----------
+<=1 2 10000
+<=2 1 10000
+<=3 1 10000
+<=4 1 10000
+<=5 1 40000
+
+Elapsed: 00:00:00.107
+Elapsed: 00:00:00.109
+SQL>
+SQL> insert /*+ APPEND */ into fact1 select num0,6,txt1 from fact1;
+
+80,000 rows inserted.
+
+Elapsed: 00:00:00.549
+SQL> commit;
+
+Commit complete.
+
+Elapsed: 00:00:00.091
+SQL> @stat
+SQL> select table_name,num_rows,sample_size,stale_stats from user_tab_statistics where table_name = 'FACT1';
+
+TABLE_NAME NUM_ROWS SAMPLE_SIZE STA
+------------------------------ ---------- ----------- ---
+FACT1 160000 160000 NO
+
+Elapsed: 00:00:00.109
+SQL>
+SQL> select table_name,column_name,low_value,high_value,sample_size,histogram from user_tab_col_statistics where table_name = 'FACT1';
+
+TABLE_NAME COLUMN_NAME LOW_VALUE HIGH_VALUE SAMPLE_SIZE HISTOGRAM
+------------------------------ ------------------------------ ------------------------------ ------------------------------ ----------- ---------------
+FACT1 NUM0 C102 C302 160000 HYBRID
+FACT1 NUM1 C102 C107 160000 FREQUENCY
+FACT1 TXT1 58585831 58585839393939 160000 HYBRID
+
+Elapsed: 00:00:00.124
+SQL>
+SQL> SELECT '<=' || endpoint_value AS range,
+ 2 endpoint_value - (LAG(endpoint_value, 1, -1) OVER (ORDER BY endpoint_value)+1) + 1 AS vals_in_range,
+ 3 endpoint_number - LAG(endpoint_number, 1, 0) OVER (ORDER BY endpoint_value) AS frequency
+ 4 FROM user_tab_histograms
+ 5 WHERE table_name = 'FACT1'
+ 6 AND column_name = 'NUM1'
+ 7 ORDER BY endpoint_value;
+
+RANGE VALS_IN_RANGE FREQUENCY
+---------- ------------- ----------
+<=1 2 10000
+<=2 1 10000
+<=3 1 10000
+<=4 1 10000
+<=5 1 40000
+<=6 1 80000
+
+6 rows selected.
+
+Elapsed: 00:00:00.114
+Elapsed: 00:00:00.114
+SQL>
+SQL> insert /*+ APPEND */ into fact1 select num0,7,txt1 from fact1;
+
+160,000 rows inserted.
+
+Elapsed: 00:00:00.650
+SQL> commit;
+
+Commit complete.
+
+Elapsed: 00:00:00.094
+SQL> @stat
+SQL> select table_name,num_rows,sample_size,stale_stats from user_tab_statistics where table_name = 'FACT1';
+
+TABLE_NAME NUM_ROWS SAMPLE_SIZE STA
+------------------------------ ---------- ----------- ---
+FACT1 320000 320000 NO
+
+Elapsed: 00:00:00.105
+SQL>
+SQL> select table_name,column_name,low_value,high_value,sample_size,histogram from user_tab_col_statistics where table_name = 'FACT1';
+
+TABLE_NAME COLUMN_NAME LOW_VALUE HIGH_VALUE SAMPLE_SIZE HISTOGRAM
+------------------------------ ------------------------------ ------------------------------ ------------------------------ ----------- ---------------
+FACT1 NUM0 C102 C302 320000 HYBRID
+FACT1 NUM1 C102 C108 320000 FREQUENCY
+FACT1 TXT1 58585831 58585839393939 320000 HYBRID
+
+Elapsed: 00:00:00.129
+SQL>
+SQL> SELECT '<=' || endpoint_value AS range,
+ 2 endpoint_value - (LAG(endpoint_value, 1, -1) OVER (ORDER BY endpoint_value)+1) + 1 AS vals_in_range,
+ 3 endpoint_number - LAG(endpoint_number, 1, 0) OVER (ORDER BY endpoint_value) AS frequency
+ 4 FROM user_tab_histograms
+ 5 WHERE table_name = 'FACT1'
+ 6 AND column_name = 'NUM1'
+ 7 ORDER BY endpoint_value;
+
+RANGE VALS_IN_RANGE FREQUENCY
+---------- ------------- ----------
+<=1 2 10000
+<=2 1 10000
+<=3 1 10000
+<=4 1 10000
+<=5 1 40000
+<=6 1 80000
+<=7 1 160000
+
+7 rows selected.
+
+Elapsed: 00:00:00.113
+Elapsed: 00:00:00.114
+SQL>
+SQL> insert /*+ APPEND */ into fact1 select num0,8,txt1 from fact1;
+
+320,000 rows inserted.
+
+Elapsed: 00:00:00.843
+SQL> commit;
+
+Commit complete.
+
+Elapsed: 00:00:00.093
+SQL> @stat
+SQL> select table_name,num_rows,sample_size,stale_stats from user_tab_statistics where table_name = 'FACT1';
+
+TABLE_NAME NUM_ROWS SAMPLE_SIZE STA
+------------------------------ ---------- ----------- ---
+FACT1 640000 640000 NO
+
+Elapsed: 00:00:00.116
+SQL>
+SQL> select table_name,column_name,low_value,high_value,sample_size,histogram from user_tab_col_statistics where table_name = 'FACT1';
+
+TABLE_NAME COLUMN_NAME LOW_VALUE HIGH_VALUE SAMPLE_SIZE HISTOGRAM
+------------------------------ ------------------------------ ------------------------------ ------------------------------ ----------- ---------------
+FACT1 NUM0 C102 C302 640000 HYBRID
+FACT1 NUM1 C102 C109 640000 FREQUENCY
+FACT1 TXT1 58585831 58585839393939 640000 HYBRID
+
+Elapsed: 00:00:00.116
+SQL>
+SQL> SELECT '<=' || endpoint_value AS range,
+ 2 endpoint_value - (LAG(endpoint_value, 1, -1) OVER (ORDER BY endpoint_value)+1) + 1 AS vals_in_range,
+ 3 endpoint_number - LAG(endpoint_number, 1, 0) OVER (ORDER BY endpoint_value) AS frequency
+ 4 FROM user_tab_histograms
+ 5 WHERE table_name = 'FACT1'
+ 6 AND column_name = 'NUM1'
+ 7 ORDER BY endpoint_value;
+
+RANGE VALS_IN_RANGE FREQUENCY
+---------- ------------- ----------
+<=1 2 10000
+<=2 1 10000
+<=3 1 10000
+<=4 1 10000
+<=5 1 40000
+<=6 1 80000
+<=7 1 160000
+<=8 1 320000
+
+8 rows selected.
+
+Elapsed: 00:00:00.111
+Elapsed: 00:00:00.112
+SQL>
+SQL> insert /*+ APPEND */ into fact1 select num0,9,txt1 from fact1;
+
+640,000 rows inserted.
+
+Elapsed: 00:00:01.310
+SQL> commit;
+
+Commit complete.
+
+Elapsed: 00:00:00.093
+SQL> @stat
+SQL> select table_name,num_rows,sample_size,stale_stats from user_tab_statistics where table_name = 'FACT1';
+
+TABLE_NAME NUM_ROWS SAMPLE_SIZE STA
+------------------------------ ---------- ----------- ---
+FACT1 1280000 1280000 NO
+
+Elapsed: 00:00:00.112
+SQL>
+SQL> select table_name,column_name,low_value,high_value,sample_size,histogram from user_tab_col_statistics where table_name = 'FACT1';
+
+TABLE_NAME COLUMN_NAME LOW_VALUE HIGH_VALUE SAMPLE_SIZE HISTOGRAM
+------------------------------ ------------------------------ ------------------------------ ------------------------------ ----------- ---------------
+FACT1 NUM0 C102 C302 1280000 HYBRID
+FACT1 NUM1 C102 C10A 1280000 FREQUENCY
+FACT1 TXT1 58585831 58585839393939 1280000 HYBRID
+
+Elapsed: 00:00:00.095
+SQL>
+SQL> SELECT '<=' || endpoint_value AS range,
+ 2 endpoint_value - (LAG(endpoint_value, 1, -1) OVER (ORDER BY endpoint_value)+1) + 1 AS vals_in_range,
+ 3 endpoint_number - LAG(endpoint_number, 1, 0) OVER (ORDER BY endpoint_value) AS frequency
+ 4 FROM user_tab_histograms
+ 5 WHERE table_name = 'FACT1'
+ 6 AND column_name = 'NUM1'
+ 7 ORDER BY endpoint_value;
+
+RANGE VALS_IN_RANGE FREQUENCY
+---------- ------------- ----------
+<=1 2 10000
+<=2 1 10000
+<=3 1 10000
+<=4 1 10000
+<=5 1 40000
+<=6 1 80000
+<=7 1 160000
+<=8 1 320000
+<=9 1 640000
+
+9 rows selected.
+
+Elapsed: 00:00:00.101
+Elapsed: 00:00:00.101
+SQL>
+SQL> insert /*+ APPEND */ into fact1 select num0,10,txt1 from fact1;
+
+1,280,000 rows inserted.
+
+Elapsed: 00:00:02.221
+SQL> commit;
+
+Commit complete.
+
+Elapsed: 00:00:00.093
+SQL> @stat
+SQL> select table_name,num_rows,sample_size,stale_stats from user_tab_statistics where table_name = 'FACT1';
+
+TABLE_NAME NUM_ROWS SAMPLE_SIZE STA
+------------------------------ ---------- ----------- ---
+FACT1 2560000 2560000 NO
+
+Elapsed: 00:00:00.125
+SQL>
+SQL> select table_name,column_name,low_value,high_value,sample_size,histogram from user_tab_col_statistics where table_name = 'FACT1';
+
+TABLE_NAME COLUMN_NAME LOW_VALUE HIGH_VALUE SAMPLE_SIZE HISTOGRAM
+------------------------------ ------------------------------ ------------------------------ ------------------------------ ----------- ---------------
+FACT1 NUM0 C102 C302 2560000 HYBRID
+FACT1 NUM1 C102 C10B 2560000 FREQUENCY
+FACT1 TXT1 58585831 58585839393939 2560000 HYBRID
+
+Elapsed: 00:00:00.104
+SQL>
+SQL> SELECT '<=' || endpoint_value AS range,
+ 2 endpoint_value - (LAG(endpoint_value, 1, -1) OVER (ORDER BY endpoint_value)+1) + 1 AS vals_in_range,
+ 3 endpoint_number - LAG(endpoint_number, 1, 0) OVER (ORDER BY endpoint_value) AS frequency
+ 4 FROM user_tab_histograms
+ 5 WHERE table_name = 'FACT1'
+ 6 AND column_name = 'NUM1'
+ 7 ORDER BY endpoint_value;
+
+RANGE VALS_IN_RANGE FREQUENCY
+---------- ------------- ----------
+<=1 2 10000
+<=2 1 10000
+<=3 1 10000
+<=4 1 10000
+<=5 1 40000
+<=6 1 80000
+<=7 1 160000
+<=8 1 320000
+<=9 1 640000
+<=10 1 1280000
+
+10 rows selected.
+
+Elapsed: 00:00:00.096
+Elapsed: 00:00:00.097
+SQL>
+SQL> insert /*+ APPEND */ into fact1 select num0,11,txt1 from fact1;
+
+2,560,000 rows inserted.
+
+Elapsed: 00:00:03.983
+SQL> commit;
+
+Commit complete.
+
+Elapsed: 00:00:00.093
+SQL> @stat
+SQL> select table_name,num_rows,sample_size,stale_stats from user_tab_statistics where table_name = 'FACT1';
+
+TABLE_NAME NUM_ROWS SAMPLE_SIZE STA
+------------------------------ ---------- ----------- ---
+FACT1 5120000 5120000 NO
+
+Elapsed: 00:00:00.105
+SQL>
+SQL> select table_name,column_name,low_value,high_value,sample_size,histogram from user_tab_col_statistics where table_name = 'FACT1';
+
+TABLE_NAME COLUMN_NAME LOW_VALUE HIGH_VALUE SAMPLE_SIZE HISTOGRAM
+------------------------------ ------------------------------ ------------------------------ ------------------------------ ----------- ---------------
+FACT1 NUM0 C102 C302 5120000 HYBRID
+FACT1 NUM1 C102 C10C 5120000 FREQUENCY
+FACT1 TXT1 58585831 58585839393939 5120000 HYBRID
+
+Elapsed: 00:00:00.096
+SQL>
+SQL> SELECT '<=' || endpoint_value AS range,
+ 2 endpoint_value - (LAG(endpoint_value, 1, -1) OVER (ORDER BY endpoint_value)+1) + 1 AS vals_in_range,
+ 3 endpoint_number - LAG(endpoint_number, 1, 0) OVER (ORDER BY endpoint_value) AS frequency
+ 4 FROM user_tab_histograms
+ 5 WHERE table_name = 'FACT1'
+ 6 AND column_name = 'NUM1'
+ 7 ORDER BY endpoint_value;
+
+RANGE VALS_IN_RANGE FREQUENCY
+---------- ------------- ----------
+<=1 2 10000
+<=2 1 10000
+<=3 1 10000
+<=4 1 10000
+<=5 1 40000
+<=6 1 80000
+<=7 1 160000
+<=8 1 320000
+<=9 1 640000
+<=10 1 1280000
+<=11 1 2560000
+
+11 rows selected.
+
+Elapsed: 00:00:00.096
+Elapsed: 00:00:00.096
+SQL>
+SQL> insert /*+ APPEND */ into fact1 select num0,12,txt1 from fact1;
+
+5,120,000 rows inserted.
+
+Elapsed: 00:00:07.347
+SQL> commit;
+
+Commit complete.
+
+Elapsed: 00:00:00.094
+SQL> @stat
+SQL> select table_name,num_rows,sample_size,stale_stats from user_tab_statistics where table_name = 'FACT1';
+
+TABLE_NAME NUM_ROWS SAMPLE_SIZE STA
+------------------------------ ---------- ----------- ---
+FACT1 10240000 10240000 NO
+
+Elapsed: 00:00:00.105
+SQL>
+SQL> select table_name,column_name,low_value,high_value,sample_size,histogram from user_tab_col_statistics where table_name = 'FACT1';
+
+TABLE_NAME COLUMN_NAME LOW_VALUE HIGH_VALUE SAMPLE_SIZE HISTOGRAM
+------------------------------ ------------------------------ ------------------------------ ------------------------------ ----------- ---------------
+FACT1 NUM0 C102 C302 10240000 HYBRID
+FACT1 NUM1 C102 C10D 10240000 FREQUENCY
+FACT1 TXT1 58585831 58585839393939 10240000 HYBRID
+
+Elapsed: 00:00:00.096
+SQL>
+SQL> SELECT '<=' || endpoint_value AS range,
+ 2 endpoint_value - (LAG(endpoint_value, 1, -1) OVER (ORDER BY endpoint_value)+1) + 1 AS vals_in_range,
+ 3 endpoint_number - LAG(endpoint_number, 1, 0) OVER (ORDER BY endpoint_value) AS frequency
+ 4 FROM user_tab_histograms
+ 5 WHERE table_name = 'FACT1'
+ 6 AND column_name = 'NUM1'
+ 7 ORDER BY endpoint_value;
+
+RANGE VALS_IN_RANGE FREQUENCY
+---------- ------------- ----------
+<=1 2 10000
+<=2 1 10000
+<=3 1 10000
+<=4 1 10000
+<=5 1 40000
+<=6 1 80000
+<=7 1 160000
+<=8 1 320000
+<=9 1 640000
+<=10 1 1280000
+<=11 1 2560000
+<=12 1 5120000
+
+12 rows selected.
+
+Elapsed: 00:00:00.109
+Elapsed: 00:00:00.110
+SQL>
+SQL> insert /*+ APPEND */ into fact1 select num0,13,txt1 from fact1;
+
+10,240,000 rows inserted.
+
+Elapsed: 00:00:14.179
+SQL> commit;
+
+Commit complete.
+
+Elapsed: 00:00:00.100
+SQL> @stat
+SQL> select table_name,num_rows,sample_size,stale_stats from user_tab_statistics where table_name = 'FACT1';
+
+TABLE_NAME NUM_ROWS SAMPLE_SIZE STA
+------------------------------ ---------- ----------- ---
+FACT1 20480000 20480000 NO
+
+Elapsed: 00:00:00.106
+SQL>
+SQL> select table_name,column_name,low_value,high_value,sample_size,histogram from user_tab_col_statistics where table_name = 'FACT1';
+
+TABLE_NAME COLUMN_NAME LOW_VALUE HIGH_VALUE SAMPLE_SIZE HISTOGRAM
+------------------------------ ------------------------------ ------------------------------ ------------------------------ ----------- ---------------
+FACT1 NUM0 C102 C302 20480000 HYBRID
+FACT1 NUM1 C102 C10E 20480000 FREQUENCY
+FACT1 TXT1 58585831 58585839393939 20480000 HYBRID
+
+Elapsed: 00:00:00.096
+SQL>
+SQL> SELECT '<=' || endpoint_value AS range,
+ 2 endpoint_value - (LAG(endpoint_value, 1, -1) OVER (ORDER BY endpoint_value)+1) + 1 AS vals_in_range,
+ 3 endpoint_number - LAG(endpoint_number, 1, 0) OVER (ORDER BY endpoint_value) AS frequency
+ 4 FROM user_tab_histograms
+ 5 WHERE table_name = 'FACT1'
+ 6 AND column_name = 'NUM1'
+ 7 ORDER BY endpoint_value;
+
+RANGE VALS_IN_RANGE FREQUENCY
+---------- ------------- ----------
+<=1 2 10000
+<=2 1 10000
+<=3 1 10000
+<=4 1 10000
+<=5 1 40000
+<=6 1 80000
+<=7 1 160000
+<=8 1 320000
+<=9 1 640000
+<=10 1 1280000
+<=11 1 2560000
+<=12 1 5120000
+<=13 1 10240000
+
+13 rows selected.
+
+Elapsed: 00:00:00.110
+Elapsed: 00:00:00.112
+SQL>
+SQL> insert /*+ APPEND */ into fact1 select num0,14,txt1 from fact1;
+
+20,480,000 rows inserted.
+
+Elapsed: 00:00:28.312
+SQL> commit;
+
+Commit complete.
+
+Elapsed: 00:00:00.099
+SQL> @stat
+SQL> select table_name,num_rows,sample_size,stale_stats from user_tab_statistics where table_name = 'FACT1';
+
+TABLE_NAME NUM_ROWS SAMPLE_SIZE STA
+------------------------------ ---------- ----------- ---
+FACT1 40960000 40960000 NO
+
+Elapsed: 00:00:00.107
+SQL>
+SQL> select table_name,column_name,low_value,high_value,sample_size,histogram from user_tab_col_statistics where table_name = 'FACT1';
+
+TABLE_NAME COLUMN_NAME LOW_VALUE HIGH_VALUE SAMPLE_SIZE HISTOGRAM
+------------------------------ ------------------------------ ------------------------------ ------------------------------ ----------- ---------------
+FACT1 NUM0 C102 C302 40960000 HYBRID
+FACT1 NUM1 C102 C10F 40960000 FREQUENCY
+FACT1 TXT1 58585831 58585839393939 40960000 HYBRID
+
+Elapsed: 00:00:00.094
+SQL>
+SQL> SELECT '<=' || endpoint_value AS range,
+ 2 endpoint_value - (LAG(endpoint_value, 1, -1) OVER (ORDER BY endpoint_value)+1) + 1 AS vals_in_range,
+ 3 endpoint_number - LAG(endpoint_number, 1, 0) OVER (ORDER BY endpoint_value) AS frequency
+ 4 FROM user_tab_histograms
+ 5 WHERE table_name = 'FACT1'
+ 6 AND column_name = 'NUM1'
+ 7 ORDER BY endpoint_value;
+
+RANGE VALS_IN_RANGE FREQUENCY
+---------- ------------- ----------
+<=1 2 10000
+<=2 1 10000
+<=3 1 10000
+<=4 1 10000
+<=5 1 40000
+<=6 1 80000
+<=7 1 160000
+<=8 1 320000
+<=9 1 640000
+<=10 1 1280000
+<=11 1 2560000
+<=12 1 5120000
+<=13 1 10240000
+<=14 1 20480000
+
+14 rows selected.
+
+Elapsed: 00:00:00.095
+Elapsed: 00:00:00.096
+SQL>
+SQL> insert /*+ APPEND */ into fact1 select num0,15,txt1 from fact1;
+
+40,960,000 rows inserted.
+
+Elapsed: 00:00:55.661
+SQL> commit;
+
+Commit complete.
+
+Elapsed: 00:00:00.141
+SQL> @stat
+SQL> select table_name,num_rows,sample_size,stale_stats from user_tab_statistics where table_name = 'FACT1';
+
+TABLE_NAME NUM_ROWS SAMPLE_SIZE STA
+------------------------------ ---------- ----------- ---
+FACT1 81920000 81920000 NO
+
+Elapsed: 00:00:00.104
+SQL>
+SQL> select table_name,column_name,low_value,high_value,sample_size,histogram from user_tab_col_statistics where table_name = 'FACT1';
+
+TABLE_NAME COLUMN_NAME LOW_VALUE HIGH_VALUE SAMPLE_SIZE HISTOGRAM
+------------------------------ ------------------------------ ------------------------------ ------------------------------ ----------- ---------------
+FACT1 NUM0 C102 C302 81920000 HYBRID
+FACT1 NUM1 C102 C110 81920000 FREQUENCY
+FACT1 TXT1 58585831 58585839393939 81920000 HYBRID
+
+Elapsed: 00:00:00.111
+SQL>
+SQL> SELECT '<=' || endpoint_value AS range,
+ 2 endpoint_value - (LAG(endpoint_value, 1, -1) OVER (ORDER BY endpoint_value)+1) + 1 AS vals_in_range,
+ 3 endpoint_number - LAG(endpoint_number, 1, 0) OVER (ORDER BY endpoint_value) AS frequency
+ 4 FROM user_tab_histograms
+ 5 WHERE table_name = 'FACT1'
+ 6 AND column_name = 'NUM1'
+ 7 ORDER BY endpoint_value;
+
+RANGE VALS_IN_RANGE FREQUENCY
+---------- ------------- ----------
+<=1 2 10000
+<=2 1 10000
+<=3 1 10000
+<=4 1 10000
+<=5 1 40000
+<=6 1 80000
+<=7 1 160000
+<=8 1 320000
+<=9 1 640000
+<=10 1 1280000
+<=11 1 2560000
+<=12 1 5120000
+<=13 1 10240000
+<=14 1 20480000
+<=15 1 40960000
+
+15 rows selected.
+
+Elapsed: 00:00:00.104
+Elapsed: 00:00:00.110
+SQL>
+SQL> insert /*+ APPEND */ into fact1 select num0,16,txt1 from fact1;
+
+81,920,000 rows inserted.
+
+Elapsed: 00:00:49.425
+SQL> commit;
+
+Commit complete.
+
+Elapsed: 00:00:00.121
+SQL> @stat
+SQL> select table_name,num_rows,sample_size,stale_stats from user_tab_statistics where table_name = 'FACT1';
+
+TABLE_NAME NUM_ROWS SAMPLE_SIZE STA
+------------------------------ ---------- ----------- ---
+FACT1 163840000 163840000 NO
+
+Elapsed: 00:00:00.098
+SQL>
+SQL> select table_name,column_name,low_value,high_value,sample_size,histogram from user_tab_col_statistics where table_name = 'FACT1';
+
+TABLE_NAME COLUMN_NAME LOW_VALUE HIGH_VALUE SAMPLE_SIZE HISTOGRAM
+------------------------------ ------------------------------ ------------------------------ ------------------------------ ----------- ---------------
+FACT1 NUM0 C102 C302 163840000 HYBRID
+FACT1 NUM1 C102 C111 163840000 FREQUENCY
+FACT1 TXT1 58585831 58585839393939 163840000 HYBRID
+
+Elapsed: 00:00:00.094
+SQL>
+SQL> SELECT '<=' || endpoint_value AS range,
+ 2 endpoint_value - (LAG(endpoint_value, 1, -1) OVER (ORDER BY endpoint_value)+1) + 1 AS vals_in_range,
+ 3 endpoint_number - LAG(endpoint_number, 1, 0) OVER (ORDER BY endpoint_value) AS frequency
+ 4 FROM user_tab_histograms
+ 5 WHERE table_name = 'FACT1'
+ 6 AND column_name = 'NUM1'
+ 7 ORDER BY endpoint_value;
+
+RANGE VALS_IN_RANGE FREQUENCY
+---------- ------------- ----------
+<=1 2 10000
+<=2 1 10000
+<=3 1 10000
+<=4 1 10000
+<=5 1 40000
+<=6 1 80000
+<=7 1 160000
+<=8 1 320000
+<=9 1 640000
+<=10 1 1280000
+<=11 1 2560000
+<=12 1 5120000
+<=13 1 10240000
+<=14 1 20480000
+<=15 1 40960000
+<=16 1 81920000
+
+16 rows selected.
+
+Elapsed: 00:00:00.094
+Elapsed: 00:00:00.095
+SQL> spool off
diff --git a/optimizer/autonomous/stats_on_load/test_load.sql b/optimizer/autonomous/stats_on_load/test_load.sql
new file mode 100644
index 00000000..551e030a
--- /dev/null
+++ b/optimizer/autonomous/stats_on_load/test_load.sql
@@ -0,0 +1,115 @@
+REM
+REM Demo direct path loading and stats maintenance.
+REM
+set timing on
+column stale format a5
+column table_name format a30
+column column_name format a30
+column high_value format a30
+column low_value format a30
+column range format a10
+set linesize 250
+set tab off
+set trims on
+set echo on
+
+spool test_load
+
+drop table fact1 purge;
+drop table fact1_source purge;
+
+create table fact1 (num0 number(10), num1 number(10), txt1 varchar2(100));
+
+create table fact1_source as
+select * from fact1 where 1=-1;
+
+insert /*+ APPEND */ into fact1_source
+select rownum,mod(rownum,10),'XXX'||rownum
+from dual connect by rownum <= 10000;
+
+commit;
+
+--
+-- Notice that NUM_ROWS is maintained - we have stats on initial load
+--
+select table_name,num_rows from user_tables where table_name = 'FACT1_SOURCE';
+
+pause p...
+
+--
+-- Insert more rows into FACT1
+--
+insert /*+ APPEND */ into fact1 select num0,1,txt1 from fact1_source;
+commit;
+@stat
+
+-- Notice above that statistics are still maintained
+-- even though FACT1 was not empty before
+-- the INSERT. The histograms are maintained too.
+pause p...
+
+insert /*+ APPEND */ into fact1 select num0,2,txt1 from fact1_source;
+commit;
+@stat
+
+-- Notice again - statistics are still maintained
+-- even though FACT1 was not empty before
+-- the INSERT. The histograms continue to be maintained.
+pause p...
+
+insert /*+ APPEND */ into fact1 select num0,3,txt1 from fact1_source;
+commit;
+@stat
+
+insert /*+ APPEND */ into fact1 select num0,4,txt1 from fact1_source;
+commit;
+@stat
+
+insert /*+ APPEND */ into fact1 select num0,5,txt1 from fact1;
+commit;
+@stat
+
+insert /*+ APPEND */ into fact1 select num0,6,txt1 from fact1;
+commit;
+@stat
+
+insert /*+ APPEND */ into fact1 select num0,7,txt1 from fact1;
+commit;
+@stat
+
+insert /*+ APPEND */ into fact1 select num0,8,txt1 from fact1;
+commit;
+@stat
+
+insert /*+ APPEND */ into fact1 select num0,9,txt1 from fact1;
+commit;
+@stat
+
+insert /*+ APPEND */ into fact1 select num0,10,txt1 from fact1;
+commit;
+@stat
+
+insert /*+ APPEND */ into fact1 select num0,11,txt1 from fact1;
+commit;
+@stat
+
+insert /*+ APPEND */ into fact1 select num0,12,txt1 from fact1;
+commit;
+@stat
+
+insert /*+ APPEND */ into fact1 select num0,13,txt1 from fact1;
+commit;
+@stat
+
+insert /*+ APPEND */ into fact1 select num0,14,txt1 from fact1;
+commit;
+@stat
+
+insert /*+ APPEND */ into fact1 select num0,15,txt1 from fact1;
+commit;
+@stat
+
+insert /*+ APPEND */ into fact1 select num0,16,txt1 from fact1;
+commit;
+@stat
+spool off
diff --git a/optimizer/autonomous/stats_on_load/user.sql b/optimizer/autonomous/stats_on_load/user.sql
new file mode 100644
index 00000000..fb1179d2
--- /dev/null
+++ b/optimizer/autonomous/stats_on_load/user.sql
@@ -0,0 +1,15 @@
+--
+-- Log into admin account and create a test user as follows
+--
+create user adwu1 identified by "choose your password";
+
+grant ALTER SESSION to adwu1;
+grant CREATE TABLE to adwu1;
+grant CREATE VIEW to adwu1;
+grant CREATE SESSION to adwu1;
+grant SELECT on dba_sql_plan_baselines to adwu1;
+grant EXECUTE on dbms_result_cache to adwu1;
+--
+grant select on v$session to adwu1;
+grant select on v$sql_plan to adwu1;
+grant select on v$sql to adwu1;
From cd65676a380b897c3d3d6b1045c042721cdab436 Mon Sep 17 00:00:00 2001
From: nigelbayliss
Date: Wed, 9 May 2018 10:57:36 +0100
Subject: [PATCH 71/92] rm file
---
optimizer/autonomous/README.md | 11 +++++++++++
1 file changed, 11 insertions(+)
create mode 100644 optimizer/autonomous/README.md
diff --git a/optimizer/autonomous/README.md b/optimizer/autonomous/README.md
new file mode 100644
index 00000000..dfeabb88
--- /dev/null
+++ b/optimizer/autonomous/README.md
@@ -0,0 +1,11 @@
+This directory contains examples dedicated the topic of the autonomous Oracle Optimizer.
+
+Unless otherwise stated, I used SQLCL to connect to the cloud database as follows:
+
+