Kris' blog

Stuff mostly around Oracle SQL Developer, Data Modeler, the APEX Listener and other general Oracle development thing in general.

Wednesday, February 08, 2012

SQL Developer 3.1 and Obfuscation

SQL Developer 3.1 , SQL Developer Datamodeler 3.1, and the OTN DB VM were all released yesterday.  Now it's time to blog about some of the new features included in these releases.  Be sure to check out the various blogs the team has.  There's a listing on OTN here.

First up from me is PL/SQL Obfuscation.  The idea is to simply make the code unreadable.  This is done in various language mostly for protection of the intelectual property.  The website, http://perl.plover.com/obfuscated/ shows this examplefrom a contest that used to run for Perl.


@P=split//,".URRUU\c8R";@d=split//,"\nrekcah xinU / lreP rehtona tsuJ";sub p{
@p{"r$p","u$p"}=(P,P);pipe"r$p","u$p";++$p;($q*=2)+=$f=!fork;map{$P=$P[$f^ord
($p{$_})&6];$p{$_}=/ ^$P/ix?$P:close$_}keys%p}p;p;p;p;p;map{$p{$_}=~/^[P.]/&&
close$_}%p;wait until$?;map{/^r/&&<$_>}%p;$_=$d[$q];sleep rand(2)if/\S/;print

The PL/SQL one SQL Developer now has isn't to this extreme but does make the code quite difficult to read.  If someone obfuscated and then wrapped the code, that would be 2 hurdles in the way to assist licensing and other agreements to protect the IP invested.


Here's the steps to try it out.

1) Open a PL/SQL Object.  This is a package I have that mirror DBMS_OUTPUT but send to a pipe instead.  It allows me to basically do a tail -f on my code's log messages and watch it as it processes.  If anyone is interested in that I can write it up another time.




2) Right click and choose Obfuscate...


3) SQL Developer will prompt to save the non-obfuscated code so there is a readable copy.


4) Check out the sources.  It can be undone by a determined person quite easy with a lot of search and replace but at least it puts a hurdle in the way.

create or replace
PACKAGE BODY pipe_output IS
PROCEDURE set_pipeoutput_on IS
-- Opens the communication pipe
BEGIN
   pv_pipe_on_bln := TRUE;
END set_pipeoutput_on;

PROCEDURE put_line (p_pipe_name VARCHAR2,p_message_txt VARCHAR2) IS
-- Sends the username of the executing user and a message to the pipe
  "CpaX6WrU0YmLxF5r4E46dw==" PLS_INTEGER;
 "Y1QFM4yVoF5S9b7fNyG/YQ==" varchar2(4000);
BEGIN
    if ( pv_pipe_on_bln ) then
      "Y1QFM4yVoF5S9b7fNyG/YQ==" := to_char(systimestamp,'HH24:MI:SS.FF6') ||':'||p_message_txt;
      DBMS_PIPE.PACK_MESSAGE("Y1QFM4yVoF5S9b7fNyG/YQ==");
      "CpaX6WrU0YmLxF5r4E46dw==" := DBMS_PIPE.SEND_MESSAGE(p_pipe_name,0.0001);
    end if;
END put_line;

PROCEDURE put_line (p_message_txt VARCHAR2) IS
-- Sends the username of the executing user and a message to the pipe
  "CpaX6WrU0YmLxF5r4E46dw==" PLS_INTEGER;
BEGIN
   IF (pv_pipe_on_bln) THEN
      DBMS_PIPE.PACK_MESSAGE(USER);
      DBMS_PIPE.PACK_MESSAGE(p_message_txt);
      "CpaX6WrU0YmLxF5r4E46dw==" := DBMS_PIPE.SEND_MESSAGE('OUTPUT');
   END IF;
END put_line;

PROCEDURE get_line (p_waittime_num NUMBER := 1) IS
-- Monitors the pipe based on a specified wait time, reading and
-- displaying the username and messages as they are sent from the
-- executing process.
   "CpaX6WrU0YmLxF5r4E46dw=="            PLS_INTEGER;
   "cy5MsI3IbOrf1eySVcYcZQ=="          VARCHAR2(30);
   "9C7AbyOB7jrbTAPf3Xpm7w=="           VARCHAR2(2000);
   "=C7AbyOB7joas2oSfUfb6NF431LXcf" BOOLEAN := FALSE;
BEGIN
   LOOP
      "CpaX6WrU0YmLxF5r4E46dw==" := DBMS_PIPE.RECEIVE_MESSAGE('OUTPUT',
         p_waittime_num);
      EXIT WHEN ("CpaX6WrU0YmLxF5r4E46dw==" != 0);
      "=C7AbyOB7joas2oSfUfb6NF431LXcf" := TRUE;
      DBMS_PIPE.UNPACK_MESSAGE("cy5MsI3IbOrf1eySVcYcZQ==");
      DBMS_PIPE.UNPACK_MESSAGE("9C7AbyOB7jrbTAPf3Xpm7w==");
      DBMS_OUTPUT.PUT_LINE(RPAD('USER: '||"cy5MsI3IbOrf1eySVcYcZQ==",30)||
                           'MESSAGE: '||"9C7AbyOB7jrbTAPf3Xpm7w==");
   END LOOP;
   IF NOT "=C7AbyOB7joas2oSfUfb6NF431LXcf" THEN
      DBMS_OUTPUT.PUT_LINE('No output in pipe.');
   END IF;
END get_line;

   PROCEDURE get_line (p_pipe_name VARCHAR2,p_waittime_num NUMBER := 1) IS
-- Monitors the pipe based on a specified wait time, reading and
-- displaying the username and messages as they are sent from the
-- executing process.
   "CpaX6WrU0YmLxF5r4E46dw=="            PLS_INTEGER;
   "cy5MsI3IbOrf1eySVcYcZQ=="          VARCHAR2(30);
   "9C7AbyOB7jrbTAPf3Xpm7w=="           VARCHAR2(2000);
   "=C7AbyOB7joas2oSfUfb6NF431LXcf" BOOLEAN := FALSE;
BEGIN
   LOOP
      "CpaX6WrU0YmLxF5r4E46dw==" := DBMS_PIPE.RECEIVE_MESSAGE(p_pipe_name,
         p_waittime_num);
      EXIT WHEN ("CpaX6WrU0YmLxF5r4E46dw==" != 0);
      "=C7AbyOB7joas2oSfUfb6NF431LXcf" := TRUE;
      DBMS_PIPE.UNPACK_MESSAGE("cy5MsI3IbOrf1eySVcYcZQ==");
      DBMS_PIPE.UNPACK_MESSAGE("9C7AbyOB7jrbTAPf3Xpm7w==");
      DBMS_OUTPUT.PUT_LINE('MESSAGE: '||"9C7AbyOB7jrbTAPf3Xpm7w==");
   END LOOP;
   IF NOT "=C7AbyOB7joas2oSfUfb6NF431LXcf" THEN
      DBMS_OUTPUT.PUT_LINE('No output in pipe.');
   END IF;
END get_line;
PROCEDURE get_line (p_pipe_name IN VARCHAR2,p_waittime_num IN NUMBER := 1,p_message OUT VARCHAR2)
IS
-- Monitors the pipe based on a specified wait time, reading and
-- displaying the username and messages as they are sent from the
-- executing process.
   "CpaX6WrU0YmLxF5r4E46dw=="            PLS_INTEGER;
   "9C7AbyOB7jrbTAPf3Xpm7w=="           VARCHAR2(2000);
BEGIN
   LOOP
     PUT_LINE('KLRICE','Recieving');
      "CpaX6WrU0YmLxF5r4E46dw==" := DBMS_PIPE.RECEIVE_MESSAGE(p_pipe_name, p_waittime_num);
      EXIT WHEN ("CpaX6WrU0YmLxF5r4E46dw==" != 0);
      PUT_LINE('KLRICE','got something');
      DBMS_PIPE.UNPACK_MESSAGE("9C7AbyOB7jrbTAPf3Xpm7w==");
      p_message :="9C7AbyOB7jrbTAPf3Xpm7w==";
   END LOOP;
END get_line;


END pipe_output;

Tuesday, November 01, 2011

OTN Tech casts related to the DB VM image

There's going to be a pointer in the next version of the Database VM Image to some OTN Tech Casts.  This is list is from Todd in the OTN Team which anyone who knows Todd means this is no-nonsense straight with development.  I thought I should pass it along.  Here's the note from Todd:


A lot of different technologies and work has gone into the creation of this Database App Development VirtualBox image.

The selection criteria used was:

  1. Technically relevant, not marketing
  2. Interesting or enlightening
  3. Pre-View, or a look behind the scenes of where dev and engineering are headed.
Most of the OTN TechCasts are 10-15min, the guests are all from development and engineering.

Database App Development :
Engineered Systems :
Oracle Linux :
Virtualization :


Database Services in the Cloud :


Friday, October 14, 2011

Schema Diff - Part 2

After showing the new Schema Diff in SQL Developer 3.1 @ddelmoli asked about separate files per object diff instead of the monolith file of all changes.  In the next EA when it comes out, you'll get prompted for what kind of file(s) to make if any at all.  There's several new options

1. Single File - what's there now, 1 file with everything


Along with the 1 file per object is a generated file which runs all the files.
2. Separate Files - 1 file per object

3. Type Files - 1 file per type i.e. tables.sql,views.sql,...



4. Separate Directories - 1 directory for each object type with

5. Worksheet - A new worksheet is created and the sql is put in.

6. Clipboard - As it suggests, straight into the clipboard for pasting into anything else.

Please check out the exchange and log any requests you may have.  We do listen !








Tuesday, October 11, 2011

SQL Developer 3.1 EA1 - Drill Down Report

I got a question on twitter from @goryunov about how to do drill down reports.  I plan on doing a few posts on reports since so much of the dialogs have changed.  That make this the first of a few blogs on reports.

Step 1.  Right click on the User Defined Reports and choose New Report


Step 2. Create a "Departments" report by naming it and entering the SQL.  This dialog has drastically changed from what was in the previous versions.  More on that later.


Step 3. Create a "Employees By Department" report.  This report will use a bind variable from the Departments report which is the DEPARTMENT_ID column from the query.


Step 4. Now edit the Departments report and choose the Drill Down item in the left options.  Click "Add Report"  This makes a new row in the table.  The Name part is whatever name you like.  The second will be a drop list of all reports in the tool.  In this case, I scrolled down and choose my "Employees By Departments" report which is using the bind variable.

Step 5. That's all there is to it. Now when I run the Departments report there's a new menu option for all drillable reports defined in Step 4.

Step 6.  When I choose that menu option, the values require are passed along.


Monday, October 10, 2011

SQL Developer 3.1 EA1 - Schema Diff

It was great showing everyone last week at OOW what was coming.  The only thing better is giving people the software to start using.  Now that it's out, I'll do some blogging to get some of the new areas pointed out.

One of the major areas of work in SQL Developer 3.1 is the diff generation between 2 schemas.  This is completely rewritten from the ground up.  That's interesting but maybe more interesting to you is that it no longer requires the change management pack.  That means you are free to use this feature now without any worries of what is licensed and on which databases.

It's still in the normal place in the Tools menu.  The first screen now gives you more control over what you are going to want to consider is a difference.  For example, matching constraints based on the name or the definition.  If I have a check contraint in two databases both doing the same things but have different names, it will not be flagged if I choose contrants by definition.




At the end of the wizard, there is a new tree representation of the differences between the schemas.  The tree shows everything possible.  Unchecking the "Show Equal Objects" will restrict to just the ones with changes.  Then in the lower portion of the screen, you get the standard diff window that highlights the changes in the objects.






Clicking the script tab you'll see the alter statement.



The finally clicking the SQL icon in the toolbar will generate the script to sync the two connections.