Development

Mind Over Matter

Greg Pavlik - Fri, 2019-01-18 18:13
"Plotinus gave exquisitely refined expression to the ancient intuition that the material order is not the basis of the mental, but rather the reverse. This is not only an eminently rational intuition; it is perhaps the only truly rational picture of reality as a whole. Mind does not emerge from mindless matter, as modern philosophical fashion would have it. The suggestion that is does is both a logical impossibility and a phenomenological absurdity. Plotinus and his contemporaries understood that all the things that most essentially characterize the act of rational consciousness—its irreducible unity of apprehension, its teleological structure, the logical syntax of reasoning, and on and on—are intrinsically incompatible with, and could not logically emerge from, a material reality devoid of mind. At the same time, they could not fail to notice that there is a constant correlation between that act of rational consciousness and the intelligibility of being, a correlation that is all but unimaginable if the structure and ground of all reality were not already rational. Happily, in Plotinus’s time no one had yet ventured the essentially magical theory of perception as representation. Plotinus was absolutely correct, therefore, to attempt to understand the structure of the whole of reality by looking inward to the structure of the mind; and he was just as correct to suppose that the reciprocity between the mind and objective reality must indicate a reality simpler and more capacious than either: a primordial intelligence, Nous, and an original unity, the One, generating, sustaining, and encompassing all things. And no thinker of late antiquity pursued these matters with greater persistence, rigor, and originality than he did."

DB Hart commenting on the new translation of Plotinus's Enneads.

Displaying an "Unsaved Changes" Warning in Visual Builder

Shay Shmeltzer - Thu, 2019-01-10 17:14

End-users are strange. Sometime they need the system we are developing to remind them when they do silly things. For example some users want us to remind them if they are trying to navigate away from a page where they did changes to data, but didn't click "save". Below I'll show you an approach for implementing such a behavior in Oracle Visual Builder Cloud Service.

What we are going to do is cancel navigation actions until users acknowledge that they are ok to leave the page.

I will leave it up to you to decide when this should go into effect. While some people might claim that this should be the default behavior across the app, this is debatable. For example, if I go into a "create record" type of page, and then without doing any changes decide to leave that page - should I be prompted for a "you have unsaved changes" message? Isn't me leaving the page the equivalent of saying - I don't need to do changes? As you can see the decision is not clear cut - so in the demo below I let you control when we start this "changes were made" status simply by pressing a button. In real applications these can be done for example when a value in a field changes. At the end of the day, all you need to do is set a boolean variable that tracks whether we are now in "changes were made" status.

In the demo I added a simple dialog to the shell page (the page that acts as the containing template to the rest of the pages) - this dialog has a "you have unsaved changes, are you sure you want to leave?" type of warning and two buttons "Yes" and "No". (Quick tip/reminder - you can see how to add a dialog to a page here, and don't forget to include the popup import in the page's json file).

I add an action chain to the shell page that will be invoked on the vbBeforeExit event - in there I check the value of the "changes made" variable and if changes were made - I show the dialog. Then I use a return action to return an object type variable that has a boolean variable called "cancelled" set to true.  Returning such an object tells the flow to stop the navigation.

Now all I needed to add were action chains to the buttons for "yes" and "no" to close the dialog, and for the "yes" scenario to also set the changes made boolean variable to no - so the next time we click to navigate away we don't show the dialog.

Check out the video to see the runtime behavior and the various parts that make up the solution.

Categories: Development

Robinson Jeffers

Greg Pavlik - Thu, 2019-01-10 12:25
Today is the birthday of one of the most under-rated American poets (in my view, one of the best we have produced), the builder of Tor House and Hawk Tower, which can still be visited in Carmel, California. A timely documentary on an American genius.


The website for Tor House visits, a fascinating experience:

http://www.torhouse.org/

Top-N again: fetch first N rows only vs rownum

XTended Oracle SQL - Sun, 2018-12-30 05:04

Three interesting myths about rowlimiting clause vs rownum have recently been posted on our Russian forum:

  1. TopN query with rownum<=N is always faster than "fetch first N rows only" (ie. row_number()over(order by ...)<=N)
  2. “fetch first N rows only” is always faster than rownum<=N
  3. “SORT ORDER BY STOPKEY” stores just N top records during sorting, while “WINDOW SORT PUSHED RANK” sorts all input and stores all records sorted in memory.

Interestingly that after Vyacheslav posted first statement as an axiom and someone posted old tests(from 2009) and few people made own tests which showed that “fetch first N rows” is about 2-3 times faster than the query with rownum, the final decision was that “fetch first” is always faster.

First of all I want to show that statement #3 is wrong and “WINDOW SORT PUSHED RANK” with row_number works similarly as “SORT ORDER BY STOPKEY”:
It’s pretty easy to show using sort trace:
Let’s create simple small table Tests1 with 1000 rows where A is in range 1-1000 (just 1 block):

create table test1(a not null, b) as
  select level, level from dual connect by level<=1000;

alter session set max_dump_file_size=unlimited;
ALTER SESSION SET EVENTS '10032 trace name context forever, level 10';

ALTER SESSION SET tracefile_identifier = 'rownum';
select * from (select * from test1 order by a) where rownum<=10;

ALTER SESSION SET tracefile_identifier = 'rownumber';
select * from test1 order by a fetch first 10 rows only;

And we can see from the trace files that both queries did the same number of comparisons:

rownum:
----- Current SQL Statement for this session (sql_id=bbg66rcbt76zt) -----
select * from (select * from test1 order by a) where rownum<=10

---- Sort Statistics ------------------------------
Input records                             1000
Output records                            10
Total number of comparisons performed     999
  Comparisons performed by in-memory sort 999
Total amount of memory used               2048
Uses version 1 sort
---- End of Sort Statistics -----------------------

[collapse]
row_number

----- Current SQL Statement for this session (sql_id=duuy4bvaz3d0q) -----
select * from test1 order by a fetch first 10 rows only

---- Sort Statistics ------------------------------
Input records                             1000
Output records                            10
Total number of comparisons performed     999
  Comparisons performed by in-memory sort 999
Total amount of memory used               2048
Uses version 1 sort
---- End of Sort Statistics -----------------------

[collapse]

Ie. each row (except first one) was compared with the biggest value from top 10 values and since they were bigger than top 10 value, oracle doesn’t compare it with other TopN values.

And if we change the order of rows in the table both of these queries will do the same number of comparisons again:

from 999 to 0

create table test1(a not null, b) as
  select 1000-level, level from dual connect by level<=1000;

alter session set max_dump_file_size=unlimited;
ALTER SESSION SET EVENTS '10032 trace name context forever, level 10';

ALTER SESSION SET tracefile_identifier = 'rownum';
select * from (select * from test1 order by a) where rownum<=10;


ALTER SESSION SET tracefile_identifier = 'rownumber';
select * from test1 order by a fetch first 10 rows only;

[collapse]
rownum

----- Current SQL Statement for this session (sql_id=bbg66rcbt76zt) -----
select * from (select * from test1 order by a) where rownum<=10

---- Sort Statistics ------------------------------
Input records                             1000
Output records                            1000
Total number of comparisons performed     4976
  Comparisons performed by in-memory sort 4976
Total amount of memory used               2048
Uses version 1 sort
---- End of Sort Statistics -----------------------

[collapse]
row_number

----- Current SQL Statement for this session (sql_id=duuy4bvaz3d0q) -----
select * from test1 order by a fetch first 10 rows only

---- Sort Statistics ------------------------------
Input records                             1000
Output records                            1000
Total number of comparisons performed     4976
  Comparisons performed by in-memory sort 4976
Total amount of memory used               2048
Uses version 1 sort
---- End of Sort Statistics -----------------------

[collapse]

We can see that both queries required much more comparisons(4976) here, that’s because each new value is smaller than the biggest value from the topN and even smaller than lowest value, so oracle should get right position for it and it requires 5 comparisons for that (it compares with 10th value, then with 6th, 3rd, 2nd and 1st values from top10). Obviously it makes less comparisons for the first 10 rows.

Now let’s talk about statements #1 and #2:
We know that rownum forces optimizer_mode to switch to “first K rows”, because of the parameter “_optimizer_rownum_pred_based_fkr”

SQL> @param_ rownum

NAME                               VALUE  DEFLT  TYPE      DESCRIPTION
---------------------------------- ------ ------ --------- ------------------------------------------------------
_optimizer_rownum_bind_default     10     TRUE   number    Default value to use for rownum bind
_optimizer_rownum_pred_based_fkr   TRUE   TRUE   boolean   enable the use of first K rows due to rownum predicate
_px_rownum_pd                      TRUE   TRUE   boolean   turn off/on parallel rownum pushdown optimization

while fetch first/row_number doesn’t (it will be changed after the patch #22174392) and it leads to the following consequences:
1. first_rows disables serial direct reads optimization(or smartscan on Exadata), that’s why the tests with big tables showed that “fetch first” were much faster than the query with rownum.
So if we set “_serial_direct_read”=always, we get the same performance in both tests (within the margin of error).

2. In cases when index access (index full scan/index range scan) is better, CBO differently calculates the cardinality of underlying INDEX FULL(range) SCAN:
the query with rownum is optimized for first_k_rows and the cardinality of index access is equal to K rows, but CBO doesn’t reduce cardinality for “fetch first”, so the cost of index access is much higher, compare them:

rownum
SQL> explain plan for
  2  select *
  3  from (select * from test order by a,b)
  4  where rownum<=10;

--------------------------------------------------------------------------------------------
| Id  | Operation                     | Name       | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT              |            |    10 |   390 |     4   (0)| 00:00:01 |
|*  1 |  COUNT STOPKEY                |            |       |       |            |          |
|   2 |   VIEW                        |            |    10 |   390 |     4   (0)| 00:00:01 |
|   3 |    TABLE ACCESS BY INDEX ROWID| TEST       |  1000K|    12M|     4   (0)| 00:00:01 |
|   4 |     INDEX FULL SCAN           | IX_TEST_AB |    10 |       |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter(ROWNUM<=10)

[collapse]
fetch first

SQL> explain plan for
  2  select *
  3  from test
  4  order by a,b
  5  fetch first 10 rows only;

-----------------------------------------------------------------------------------------
| Id  | Operation                | Name | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT         |      |    10 |   780 |       |  5438   (1)| 00:00:01 |
|*  1 |  VIEW                    |      |    10 |   780 |       |  5438   (1)| 00:00:01 |
|*  2 |   WINDOW SORT PUSHED RANK|      |  1000K|    12M|    22M|  5438   (1)| 00:00:01 |
|   3 |    TABLE ACCESS FULL     | TEST |  1000K|    12M|       |   690   (1)| 00:00:01 |
-----------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("from$_subquery$_002"."rowlimit_$$_rownumber"<=10)
   2 - filter(ROW_NUMBER() OVER ( ORDER BY "TEST"."A","TEST"."B")<=10)

[collapse]
fetch first + first_rows

SQL> explain plan for
  2  select/*+ first_rows */ *
  3  from test
  4  order by a,b
  5  fetch first 10 rows only;

--------------------------------------------------------------------------------------------
| Id  | Operation                     | Name       | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT              |            |    10 |   780 | 27376   (1)| 00:00:02 |
|*  1 |  VIEW                         |            |    10 |   780 | 27376   (1)| 00:00:02 |
|*  2 |   WINDOW NOSORT STOPKEY       |            |  1000K|    12M| 27376   (1)| 00:00:02 |
|   3 |    TABLE ACCESS BY INDEX ROWID| TEST       |  1000K|    12M| 27376   (1)| 00:00:02 |
|   4 |     INDEX FULL SCAN           | IX_TEST_AB |  1000K|       |  2637   (1)| 00:00:01 |
--------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("from$_subquery$_002"."rowlimit_$$_rownumber"<=10)
   2 - filter(ROW_NUMBER() OVER ( ORDER BY "TEST"."A","TEST"."B")<=10)

[collapse]
fetch first + index

SQL> explain plan for
  2  select/*+ index(test (a,b)) */ *
  3  from test
  4  order by a,b
  5  fetch first 10 rows only;

--------------------------------------------------------------------------------------------
| Id  | Operation                     | Name       | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT              |            |    10 |   780 | 27376   (1)| 00:00:02 |
|*  1 |  VIEW                         |            |    10 |   780 | 27376   (1)| 00:00:02 |
|*  2 |   WINDOW NOSORT STOPKEY       |            |  1000K|    12M| 27376   (1)| 00:00:02 |
|   3 |    TABLE ACCESS BY INDEX ROWID| TEST       |  1000K|    12M| 27376   (1)| 00:00:02 |
|   4 |     INDEX FULL SCAN           | IX_TEST_AB |  1000K|       |  2637   (1)| 00:00:01 |
--------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("from$_subquery$_002"."rowlimit_$$_rownumber"<=10)
   2 - filter(ROW_NUMBER() OVER ( ORDER BY "TEST"."A","TEST"."B")<=10)

[collapse]

So in this case we can add hints “first_rows” or “index”, or install the patch #22174392.

ps. I thought to post this note later, since I hadn’t time enough to add other interesting details about the different TopN variants, including “with tie”, rank(), etc, so I’ll post another note with more details later.

Categories: Development

Connecting to Oracle Autonomous Transaction Processing (ATP) from Developer Cloud Service

Shay Shmeltzer - Mon, 2018-12-10 18:10

The latest and greatest flavor of the Oracle Database in the cloud is Oracle Autonomous Transaction Processing (ATP). One of the Autonomous DB flavors that, it is optimized for OLTP (On-Line Transaction Processing) Applications - the type that you and I usually work on.

One new feature in the world of ATP is the way that you connect to the DB, connection is done leveraging wallets to make sure that your data is secured even though you are connecting over public internet. Here are instructions on how to get such a wallet file for your instance of ATP.

We introduced an enhancement to the latest version of Developer Cloud Service that allows you to connect to ATP from your CI/CD automation jobs. This can help you automate CI/CD for SQL scripts that you need to run against that DB.

As I mentioned in past blogs, DevCS has built in support for the SQLcl utility, allowing you to run SQL scripts against an Oracle database as part of your CI/CD chain. If you want to connect the SQLcl utility in DevCS to ATP, it will need to have access to your wallet.zip file. You can achieve this by uploading the file into your git repository.

Then in your SQLcl configuration you'll specify the user/pass like before, and then point the field titled Credentials File to the wallet.zip file location. (in the screenshot below, the zip file is at the top of the git repo connected to the build - so there is no need to add a path). In the next field, titled connection string, you specify the name used in the wallet's tnsnames.ora file to connect to the DB.

Now you can continue as usual and provide inline SQL or point to SQL files from your git repository.

ATP Connection Definition

 

Categories: Development

Docker with Oracle database: install patches automatically

XTended Oracle SQL - Thu, 2018-12-06 15:10

Recently I had to install the patch for fixing cross-platform PDB transport bug onto the docker images with Oracle, so these are easy way how to do it:

1. create directory “patches” and create “install_patches.sh”:

#!/bin/bash

unzip  -u ./*.zip
CURDIR=`pwd`

for D in *; do
    if [ -d "${D}" ]; then
        echo =================================================
        echo " *** Processing patch # ${D}... "   # your processing here
        cd "${D}"
        opatch apply -silent
    fi
    cd $CURDIR
done

2. add the following commands into the dockerfile:

USER root

# Copy DB install file
COPY --chown=oracle:dba patches $INSTALL_DIR/patches

# Install DB software binaries
USER oracle
RUN chmod ug+x $INSTALL_DIR/patches/*.sh && \
    sync && \
    cd $INSTALL_DIR/patches && \
    ./install_patches.sh

3. put downloaded patches into the “patches” directory and build image.

For example, dockerfile for 18.3:

FROM oracle/database:18.3.0-ee

MAINTAINER Sayan Malakshinov <sayan@orasql.org>

USER root

# Copy patches:
COPY --chown=oracle:dba patches $INSTALL_DIR/patches

# Install patches:
USER oracle
RUN chmod ug+x $INSTALL_DIR/patches/*.sh && \
    sync && \
    cd $INSTALL_DIR/patches && \
    ./install_patches.sh

ps. I’ve also create the request for that in the official Docker github: https://github.com/oracle/docker-images/issues/1070

Categories: Development

Adding Calculated Fields to Your Visual Builder UI

Shay Shmeltzer - Tue, 2018-12-04 17:16

This is a quick blog to show two techniques for adding calculated fields to an Oracle Visual Builder application.

Both techniques do the calculation on the client side (in the browser). Keep in mind that you might want to consider doing the calculation on the back-end of your application and get the calculated value delivered directly to your client - in some cases this results in better performance. But sometimes you don't have access to modify the backend, or you can't do calculations there, so here we go:

1. For simple calculation you can just use the value property of a field to do the calculation for you.

For example if you need to know the yearly salary you can take the value in a field and just add *12 to it.

You can also use this to calculate values from multiple fields for example [[$current.data.firstName + " " +$current.data.lastName]] - will get you a field with the full name.

2. For more complex calculation you might need to write some logic to arrive at your calculated value, for example if you have multiple if/then conditions. To do that you can create a client side JavaScript function in your page's JS section. Then you refer to the function from your UI component's value attribute using something like {{$functions.myFunc($current.data.salary)}}

As you'll see in the demo, if you switch to the code view of your application the code editor in Oracle VB will give you code insight into the functions you have for your page, helping you eliminate coding errors.

Categories: Development

The Way

Greg Pavlik - Thu, 2018-11-22 13:48
Walking the Camino one meets people from all walks of life - hailing from virtually everywhere, from virtually every continent and creed. All on a path to their destination. Isn't that life itself?








Filtering Data Providers with Compound Conditions in Visual Builder

Shay Shmeltzer - Mon, 2018-11-19 13:53

I posted in the past a basic introduction to filtering lists in Visual Builder - showing how to use the filterCriterion to filter the records shown in a ServiceDataProvider. Since I recorded this video, a few things changed, and I also saw several customers asking how can they use more complex conditions that involve more than one filter.

In the video below I show how to define a basic filter with the latest versions (note that in VB 18.4.1 you no longer need to surround value with quotes ""), and then I show how to create a more complex condition that involves two filter criteria and set them to work with either an or or an and operator.

When you are using business components in Visual Builder, the filterCriterion is translated into a "q" parameter that is passed to the GET method (more about this q query parameter here). If you find that you are not getting the records you are expecting, check out the browser's Network tab to see what query parameter was passed in your call to the REST service (intro to this debugging technique here).

As you'll see the filterCriterion contains an array of "criteria" so you can specify several of them. In the video I'm using an approach that Brian Fry showed me that gives you a more declarative way to populate the array dragging and dropping multiple "criteria type" variables into the same array.

Note however that the important thing is what is actually being populated in the json file that defines the action. You should go into this view and verify that you have the right structure there. You can also directly manipulate that source to achieve the filter you need.

As you'll see in the video there are some cases where the design time for this filterCriterion adds an entry into the JSON that might not match what you want (we are tracking this issue). So as mentioned - if things don't work as expected direct manipulation of the JSON might be required. 

Categories: Development

Oracle JET UI on Top of Oracle ADF With Visual Builder

Shay Shmeltzer - Thu, 2018-11-15 13:22

At Oracle OpenWorld this year I did a session about the future of Oracle ADF, and one of the demos I did there was showing the powerful combination of Oracle ADF backend with a new Oracle JET UI layer and how Oracle Visual Builder makes this integration very simple.

While we have many happy Oracle ADF customers, we do hear from some of them about new UI requirements that might justify thinking about adopting a new UI architecture for some modules. These type of requirements align with an industry trend towards adopting a more client centric UI architecture that leverages the power of JavaScript on the client. While ADF (which is more of a server centric architecture) does let you leverage JavaScript on the client and provides hook points for that in ADF Faces, some customers prefer a more "puristic" approach for new user interfaces that they are planning to build. Oracle's solution for such a UI architecture is based on Oracle JET - an open source set of libraries we developed and share with the community at http://oraclejet.org.

Oracle Visual Builder provides developers with a simpler approach to building Oracle JET based UIs - for both web and on-device mobile applications. Focusing on a visual UI design approach it drastically reduce the amount of manual coding you need to do to create JET based UIs. 

UIs that you build in Visual Builder connect at the back to REST services, and this is where you can leverage Oracle ADF. In version 12 of JDeveloper we introduced the ability to publish ADF Business Components as REST services through a simple wizard. Note that out-of-the-box you get a very powerful set of services that support things like query by example, pagination, sorting and more. If you haven't explored this functionality already, check out the videos showing how to do it here, and this video covering cloud hosting these services.

Once you have this ADF based REST services layer - you'll be glad to hear that in Visual Builder we have specific support to simplify consuming these REST services. Specifically - we understand the meta-data descriptions that these REST services provide and then are able to create services and endpoints mapping for you.

ADF Describe Dialog in Service Connection

You leverage our "Service from specification" dialog to add your ADF services to your Visual Builder app - and from that point on, it's quite simple to build new JET UIs accessing the data.

In the video below I show how simple it is to build a JET-based on-device mobile app that leverage a set of REST services that were created from Oracle JDeveloper 12. Check it out:

Categories: Development

Conceptions of Fudo Myoo in Esoteric Buddhism

Greg Pavlik - Mon, 2018-11-12 17:14
Admittedly, this is an esoteric topic altogether - my own interest in understanding Fudo Myoo in Mahayana Buddhism have largely stemmed from an interest in Japanese art in the Edo wood block tradition - but I thought a rather interesting exploration of esoteric Buddhism and by implication currents of Japanese culture.

https://tricycle.org/magazine/evil-in-esoteric-japanese-buddhism/

On Education

Greg Pavlik - Mon, 2018-11-12 17:07
'We study to get diplomas and degrees and certifications, but imagine a life devoted to study for no other purpose than to be educated. Being educated is not the same as being informed or trained. Education is an "education", a drawing out of one's own genius, nature, and heart. The manifestation of one's essence, the unfolding of one's capacities, the revelation of one's heretofore hidden possibilities - these are the goals of study from the point of view of the person. From another side, study amplifies the speech and song of the world so that it's more palpably present.

Education in soul leads to the enchantment of the world and the attunement of self.'

Thomas Moore, 'Meditations'

Leveraging Snippets to Create Wiki Pages in Oracle Developer Cloud

Shay Shmeltzer - Fri, 2018-11-09 12:53

Snippets are a feature of Oracle Developer Cloud Service that gives you a place to store reusable pieces of code as part of your project. These are the type of code snippets that you don't want as part of your core Git repository, but that you still find useful. Snippets can be your own private ones or shared among your team.

One nice usage for code snippets is the ability to quickly include them in a wiki page. This allows you, for example, to create a template of a wiki page and then quickly apply it to a new page that you creates. Using the correct markup for your wiki page format (confluence in the example in the video), you can create a collection of templates. For example, a template for a feature page, a template for a meeting minutes page, etc.. then your team members can quickly create pages that conforms to these templates.

In the video below I show you how to leverage this combination step by step.

Categories: Development

Adding Off Canvas Layout to a Visual Builder Application

Shay Shmeltzer - Wed, 2018-11-07 15:18

Off Canvas layout is a common UI pattern for modern applications, especially on mobile devices. The concept is aimed at saving space on your page, allowing you to pop out a "drawer" of additional information. This helps reduce clatter on the main page but still provide access to important data when needed without leaving the page context. You can see an example of the runtime behavior at the top of this post. 

Oracle JET provides this type of "off-canvas" behavior as a built in component, and they have a demo of it working as part of the cookbook here.

In the video below I show you how to add this to a Visual Builder application. As always - you can mostly just copy and paste code from the JET cookbook, but you need to handle some of the importing of resources a little different, and use the Visual Builder approach for adding your JavaScript function.

The code used in the video is:

Page source:

Menu
List
chart
Gifts

JavaScript Function in the page:

define(['ojs/ojcore'], function(oj) { 'use strict'; var PageModule = function PageModule() {}; PageModule.prototype.showSide = function() { var offcanvas = { "selector": "#startDrawer", "content": "#mainContent", "edge": "start", "displayMode": "push", "size": "200px" }; oj.OffcanvasUtils.open(offcanvas); } return PageModule; });

and in your page Json file add this import:

"oj-offCanvas": { "path": "ojs/ojoffcanvas" }
Categories: Development

Working with REST POST and Other Operations in Visual Builder

Shay Shmeltzer - Fri, 2018-10-05 12:37

One of the strong features of Visual Builder Cloud Service is the ability to consume any REST service very easily. I have a video that shows you how to work with REST services in a completely declarative way, but that video doesn't show you what happens behind the scenes when you work with the quick starts. In addition, that video shows using the GET methods and several threads on our community's discussion forum asked for help working with other operations of REST.

The demo video aims to give you a better insight into working with REST operations showing how to:

  • Add service endpoints for various REST operations
  • Create a GET form manually for retrieving single records
  • Create a POST form manually
    • Create type for the request and response parameters
    • Create variables based on the types
    • Call the POST operation passing a variable as body
  • Get the returned values from the POST to show in a page or notifications

A couple of notes:

In the video I use the free REST testing platform at https://jsonplaceholder.typicode.com

While I do everything here manually - you should be able to use the quick starts for creating a "create" form and map them to the post operation - as long as you marked the specific entry as a "create" entry like I did in the demo.

If the concepts above such as types, variables, action chains are new to you - I would highly recommend watching this video on the VBCS Architecture and Building Blocks, it will help you better understand what VBCS is all about.

 

 

 

 

Categories: Development

Lizok's Bookshelf

Greg Pavlik - Sun, 2018-09-30 17:34
The first of Eugene Vodolazkin's novels translated to English was, of course, Laurus, which ranks as one of the significant literary works of the current century. I was impressed by the translators ability to convey not just a feel for what I presume the original has, but a kind of "other-time-yet-our-timeness" that seems an essential part of the authors objective. I recently picked up Volodazkin's Aviator and thought to look up the translator as well. I was delighted to find her blog on modern Russian literature, which can be found here:

http://lizoksbooks.blogspot.com/2018/09/the-2018-nose-award-longlist.html

Sea of Fertility

Greg Pavlik - Sun, 2018-09-23 18:24
In a discussion on some of my reservations on Murakami's take on 20th century Japanese literature, a friend commented on Mishima's Sea of Fertility tetrology with some real insights I thought worth preserving and sharing, albeit anonymously (if you're not into Japanese literature, now's a good time to stop reading):

"My perspective is different: it was a perfect echo of the end of “Spring Snow” and a final liberation of the main character from his self-constructed prison of beliefs. Honda’s life across the novels represents the false path: of consciousness the inglorious decay and death of the soul trapped in a repetition of situations that it cannot fathom being forced into waking. He is forced into being an observer of his own life eventually debasing himself into a “peeping Tom” even as he works as a judge. The irony is rich. Honda decays through the four novels since he clings to the memory of his friend (Kiyoaki) and does not understand the constructed nature his experience and desires. He is asleep. He wants Matsugae’s final dream to be the truth (that they will “...meet again under the Falls.”) His desires have been leading him in a circle and the final scene in the garden is his recognition of what the Abbess (Satoko from Spring Snow) was trying to convey to him. When she tells him, “There was no such person as Kiyoaki Matsugae”, it is her attempt to cure him of his delusion (and spiritual illness that has rendered him desperate and weak - chasing the ego illusions of his youth and seeking the reincarnation of his friend everywhere.) Honda lives in the dream of his ego and desire. In the final scene, he wakes up for the first time. I loved the image of the shadows falling on the garden. He is finally dying, stripped of illusion. I found it to be Mishima at his most powerful. I agree about “Sailor”, that is a great novel and much more Japanese in its economy of expression. Now, Haruki Murakami is a world apart from Kawabata and Mishima. I love his use of the unconscious/Id as a place to inform and enthrall: the labyrinth of dreams. Most of his characters are trapped (at least part of the time) in this “place”: eg Kafka on the Shore, Windup Bird Chronicle, Hard-boiled Wonderland and End of the World, etc. Literature has to have room for all of them. I like the other Murakami, Ryu Murkami, whose “Audition” and “Famous Hits of the Shōwa Era” are dark, psychotic tales of unrestrained, escalating violence but redeemed by deep probing of unconscious, hidden motives (the inhuman work of the unconscious that guides the characters like the Greek sense of fate (Moira)) and occasional black humor."
 

Business Logic for Business Object in Visual Builder - Triggers, Object Functions, Groovy and More

Shay Shmeltzer - Fri, 2018-09-14 18:15

The business objects that you create in Visual Builder Cloud Service (VBCS) are quite powerful. Not only can they store data, manage relationships, and give you a rich REST interface for interacting with them, they can also execute dedicated business logic that deals with the data.

If you click on the Business Rules section of a business object you'll see that you can create:

  • Triggers - allow you to react to data events such as insert, update, and delete on records.
  • Object and field Validators - allowing you to make sure that data at the field or record level is correct.
  • Object Functions - A way to define "service methods" that encapsulate logic related to a business object. These functions can be invoked from various points in your application, and also from outside your app.

To code logic in any of these location you will leverage the Groovy language.

I wanted to show the power of some of the functionality you can achieve with these hook points for logic. The demo scenario below is based on a requirement we got from a customer to be able to send an email with the details of all the children records that belong to a specific master record. Imagine a scenario where we have travel requests associated with specific airlines. When we go to delete an airline we want to send an email that will notify someoe about the travel requests that are going to be impacted by this change.

To achieve this I used an accessor - an object that helps you traverse relationships between the two objects - to loop over the records and collect them.

In the video below you'll see a couple of important points:

  • Business object relationship and how to locate the name of an accessor
  • Using a Trigger Event to send an email
  • Passing an object function as a parameter to an email template
  • Coding groovy in a business object

For those interested the specific Groovy code I used is:

def children = TravelRequests; // Accessor name to child collection def ret_val = "List of travel requests "; if (!children.hasNext()) { return "no impact"; } while (children.hasNext()) { def emprec = children.next(); def name = emprec.name; ret_val=ret_val+" " +name; } return ret_val;

 

By the way - if, like me, you come from a background of using Oracle ADF Business Components you might find many of the things we did here quite familiar. That's because we are leveraging Oracle ADF Business Components in this layer of Visual Builder Cloud Service. So looking up old Groovy tutorial and blogs about ADF BC might prove to be useful here too :-)

 

 

Categories: Development

EnterpriseDB Postgres for Oracle Developers

Gerger Consulting - Tue, 2018-09-11 11:22
EnterpriseDB Postgres is the only open source database in Gartner's Magic Quadrant and has virtually full feature parity with Oracle. Yet, very few of us know about it or use it. Let's change this.

Attend the webinar by two of the best people in EnterpriseDB world and learn how EDB Postgres can help you.

Register at this link.


About the Webinar:

The greatest roadblock that many organizations face in their technology transformation initiatives is their Oracle relationship. High costs and restrictive licensing are preventing many organizations from investing in strategic new data-driven initiatives that strengthen competitiveness.
Recognized by Gartner as the only open source database provider in the Magic Quadrant for Operational Database Management Systems, EDB Postgres is the leading database alternative to Oracle. With Oracle compatibility features and tools that support migrations, often in just hours or days, organizations reduce costs by 80% or more and can deploy the database anywhere without restriction.
In this webinar you’ll learn how:
  • - The EDB Postgres Platform supports Oracle’s PL/SQL and comes with enterprise-level management and diagnostic tools;

  • - EDB’s Oracle migration expertise and technology coupled with Destiny’s application migration expertise helps organizations migrate to Postgres;

  • - The EDB Postgres Platform significantly reduces an organizations TCO costs while still providing enterprise-level capabilities for business needs and applications.


Categories: Development

Increasing Maximum Web Service Requests in Oracle APEX 18.1

Dimitri Gielis - Mon, 2018-09-10 15:29
While running our final tests of APEX Office Print (AOP) 18.1 we hit "ORA-20000: Issue calling Main AOP Service (REST call: ): ORA-20001: You have exceeded the maximum number of web service requests per workspace."


When you login into the Internal Workspace and navigate to a workspace, there's a setting for  Maximum Web Service Requests. The default value is 1000 requests per 24h (rolling window).

If you know that AOP has next to hundreds of server tests, also around 500 automated tests through APEX, we hit this limit after the second full run. After setting the value to 20000, we are able to continue our final testing :)

I guess the chances are small you will hit the limit in a normal APEX app, but if you do, it's easy to fix by setting a higher value for your workspace.
Categories: Development

Pages

Subscribe to Oracle FAQ aggregator - Development