Monday, 3 June 2013

Working with PowerDesigner models through VB interface

PowerDesigner has great automation abilities. The easiest way to work with a model programmatically is to use PowerDesigner's embedded Visual Basic script interface and to run scripts through 'Edit/Run script' window.
Here's an example script that uses given color to highlight tables that have comments or that have at least one column with a comment:
Dim model
Set model = ActiveModel
For each table in model.Tables
   doPaint = false
   tableComment = Trim( table.Comment )
   if ( "" <> tableComment ) then
      doPaint = true
   end if

   if ( not doPaint ) then
      For each column in table.Columns
         comment = Trim( column.Comment )
         if ( "" <> comment ) then
            doPaint = true
            Exit For
         end if
      Next   
   end if
   
   if ( doPaint ) then
      For each symbol in table.Symbols
         symbol.BrushStyle = 6 'Gradient 
         symbol.GradientFillMode = 64
         symbol.FillColor = RGB( 252, 178, 104 ) 
         symbol.GradientEndColor = RGB( 255, 255, 255 )
      Next
   end if
Next
More info about PowerDesigner automation at SyBooks and PowerDesigner's 'Metadata Objects' help file.
Tip: when reverse engineering big unfamiliar scheme you can easily select and move apart particular symbols by adjusting their 'Position' property. For example you can select and move tables with particular prefix:
Dim model
Set model = ActiveModel
PREFIX = "hh_"
For each table in model.Tables
   tableName = LCase( Trim( table.Name ) )
   if ( PREFIX = Left( tableName, Len( prefix) ) ) then
      For each symbol in table.Symbols
         symbol.Position = NewPoint( 0, 0 )
      Next
   end if
Next
After desired symbols are moved to the (0,0) position they can be selected and arranged with 'Symbol->Auto layout command'.
This simple solution of how to distill big scheme came to me after I had reversed database with 2K of tables with a few foreign key constants defined. I faced a brick wall of tables arranged by their column count. All semantics were encoded in table names so I just had to set apart tables with equal prefixes. I've searched for a function to add symbols to selection but with no success. So I decided to move desired symbols to the center of workspace and then to select them with single mouse movement. That's when 'Auto layout' command came in very handy.

Thursday, 30 May 2013

An AHK script to select particular tables for reverse engineering in PowerDesigner

The following script helps to select tables (optionally any objects) in the 'Database Reverse Engineering' window of PowerDesigner 15.3 that are stored in txt file.
First one should unmark all objects in the list view, then run the script, hit F5, and after the selection process ends (that can be noticed by stopped blinking of the 'Database Reverse Engineering' window) hit SPACE to mark only selected objects.
Here's the resulting list:

Script uses Acc Library to get the names of items in the ListView and to select them. It should be run under one of the latest releases of AutoHotkey_L.
In my particular case file containing list of objects is called 'tables_to_reverse.txt' (see the script).

Wednesday, 29 May 2013

Reverse engineering Oracle 11gR2 scheme with Sybase PowerDesigner 12.5 on Windows 7 x64

The following setup was made to perform reverse engineering of Oracle 11gR2 scheme into physical diagram using Sybase PowerDesigner 12.5 on Windows 7 x64.
ConnectionType: JDBC
DBMS type: Oracle
User name: <your scheme name>
Password: <your password>
JDBC driver class: oracle.jdbc.driver.OracleDriver
JDBC connection URL: jdbc:oracle:thin:@//<your host>:<your port>/<your service name>
JDBC driver jar files: c:\Oracle\product\11.2.0\client_1\jdbc\lib\ojdbc6.jar
Plus had to install 32-bit Java and add edit path variable in batch file to make PowerDesigner use appropriate VM:
set path=C:\Program Files (x86)\Java\jre7\bin\client\;%path%
cd "c:\Program Files (x86)\Sybase\PowerDesigner 12\"
pdshell12.exe
Many thanks to Devtype blog and Jan Bartos' answer on google groups.

Tuesday, 28 May 2013

Two window browser setup to bypass corporate firewall using iOS hotspot

I've just changed a department and was surprised by more strict corporate rules applied to my windows account.
More blogs and sites became totally unreachable because of the corporate firewall.
So to continue productive work I rolled out the following setup:
1. Second LAN connection through iPhone 3gs' wired hotspot established.
2. Second palemoon (a firefox fork) profile created (named backdoor).
3. Second palemoon profile was assigned a different theme (and a different icon by AutoHotkey script that will be covered in the following posts).
4. A shortcut was made that binds second palemoon instance (with 'backdoor' profile) to specific LAN interface using a ForceBindIP utility:
C:\Windows\SysWOW64\ForceBindIP.exe 127.0.0.1 "C:\Program Files (x86)\Pale Moon\palemoon.exe" dummy -p backdoor -no-remote
The dummy argument is used because of the feature of the ForceBind utitlity: it does not pass the first given parameter to the program specified.
Given IP should be replaced with actual ip-address of the second LAN interface.
Now I can surf through unblocked sites through a corporate LAN and access restricted ones through an iPhone hotspot.

Monday, 29 April 2013

Integrating SyntaxHighlighter into this blog (line wrapping enabled)

Finally integrated current version of SyntaxHighlighter into this blog.
Had to include following into the head section of the blogger template:
    <!-- Include required JS files -->
    <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js' type='text/javascript'/>
     
    <!--
        At least one brush, here we choose JS. You need to include a brush for every
        language you want to highlight
    -->
    <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushBash.js' type='text/javascript'/>
    <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJscript.js' type='text/javascript'/>
    <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushSql.js' type='text/javascript'/>
    <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPython.js' type='text/javascript'/>
    <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPerl.js' type='text/javascript'/>
    <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJava.js' type='text/javascript'/>
    <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushDelphi.js' type='text/javascript'/>
    <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCss.js' type='text/javascript'/>
    <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCpp.js' type='text/javascript'/>
    <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPlain.js' type='text/javascript'/>
    <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushXml.js' type='text/javascript'/>
     
    <!-- Include *at least* the core style and default theme -->
    <link href='http://alexgorbatchev.com/pub/sh/current/styles/shCore.css' rel='stylesheet' type='text/css'/>
    <link href='http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css' rel='stylesheet' type='text/css'/>
    
    <style type='text/css'>
    /* syntaxhighlighter */
    .syntaxhighlighter .line {
            white-space: pre-wrap !important; /* make code wrap */
    }
    </style>
    <style type='text/css'>
    /* syntaxhighlighter */
    .syntaxhighlighter {
      overflow-y: hidden !important;
    }
    </style>
    
    <script src='http://code.jquery.com/jquery-1.5.2.min.js' type='text/javascript'/>
 <script type='text/javascript'>
//<![CDATA[
$(function(){
// Line wrap back
  var shLineWrap = function(){
    $('.syntaxhighlighter').each(function(){
    // Fetch
    var $sh = $(this),
        $gutter = $sh.find('td.gutter'),
        $code = $sh.find('td.code');
    // Cycle through lines
    $gutter.children('.line').each(function(i){
      // Fetch
      var $gutterLine = $(this),
          $codeLine = $code.find('.line:nth-child('+(i+1)+')');
      // Fetch height
      var height = $codeLine.height()||0;
      if ( !height ) {
        height = 'auto';
      }
      else {
        height = height += 'px';
      }
      // Copy height over
      $gutterLine.height(height+' !important');
      console.debug($gutterLine.height(), height, $gutterLine.text(), $codeLine);
    });
  });
};
 
// Line wrap back when syntax highlighter has done it's stuff
var shLineWrapWhenReady = function(){
  if ( $('.syntaxhighlighter').length === 0 ) {
    setTimeout(shLineWrapWhenReady,800);
  }
  else {
    shLineWrap();
  }
};
 
// Fire
shLineWrapWhenReady();
});
//]]></script>
    <script type='text/javascript'>
      SyntaxHighlighter.defaults['gutter'] = false;
      SyntaxHighlighter.config.bloggerMode = true;
      SyntaxHighlighter.all();
    </script>
Done it with a great help from My Tech Notes and Undume Press.
Had to turn gutter off, cause line wrapping malforms line numbering.
More to do: add visual sign of line wrapping, conditional wrapping, etc.

Tuesday, 26 February 2013

Thing to remember

Since rows can migrate from location-to-location when they are updated ROWID should never be stored an never be counted on to be the same in any database.

Friday, 22 February 2013

Oneliner to wrap long line into 80 characters

cat /dev/clipboard | perl -e 'use Text::Wrap;$Text::Wrap::columns = 160;while (<>){print wrap("","",$_);}' > /dev/clipboard

Had to set $Text::Wrap::columns to 160 to correctly wrap cyrillic characters under Cygwin 7.1.