Category Archives: powerbuilder

When creating orcascipt, usually I start from the existing PBT file which contains the huge lib list:

LibList “myapp_appl.pbl\\myapp_appl.pbl;myapp_attachment.pbl\\myapp_attachment.pbl;myapp_br.pbl\\myapp_br.pbl;myapp_casefile.pbl\\myapp_casefile.pbl;myapp_casefile_related.pbl\\myapp_casefile_related.pbl;myapp_dddw.pbl\\myapp_dddw.pbl;myapp_disciplinary_action.pbl\\myapp_disciplinary_action.pbl;myapp_licensee.pbl\\myapp_licensee.pbl;myapp_list.pbl\\myapp_list.pbl;myapp_mass_entry.pbl\\myapp_mass_entry.pbl;myapp_registration.pbl\\myapp_registration.pbl;myapp_report.pbl\\myapp_report.pbl;myapp_resource.pbl\\myapp_resource.pbl;myapp_schedule.pbl\\myapp_schedule.pbl;myapp_security.pbl\\myapp_security.pbl;myapp_ticket.pbl\\myapp_ticket.pbl;im_lls_rc_dws.pbl\\im_lls_rc_dws.pbl;im_lls_rc_rpt_dws.pbl\\im_lls_rc_rpt_dws.pbl;pies_shared.pbl\\pies_shared.pbl;reg_01.pbl\\reg_01.pbl;”

I want the orca format like this:

build executable “myapp.exe” “myapp.ico” “myapp.pbr” “yyyyyyyyyyyyyyyyyyy”

build Library “myapp_appl.pbl\myapp_appl.pbl” “” PBD
build Library “myapp_attachment.pbl\myapp_attachment.pbl” “” PBD
build Library “myapp_br.pbl\myapp_br.pbl” “” PBD
build Library “myapp_casefile.pbl\myapp_casefile.pbl” “” PBD
build Library “myapp_casefile_related.pbl\myapp_casefile_related.pbl” “” PBD
build Library “myapp_dddw.pbl\myapp_dddw.pbl” “” PBD
build Library “myapp_disciplinary_action.pbl\myapp_disciplinary_action.pbl” “” PBD
build Library “myapp_licensee.pbl\myapp_licensee.pbl” “” PBD
build Library “myapp_list.pbl\myapp_list.pbl” “” PBD
build Library “myapp_mass_entry.pbl\myapp_mass_entry.pbl” “” PBD
build Library “myapp_registration.pbl\myapp_registration.pbl” “” PBD
build Library “myapp_report.pbl\myapp_report.pbl” “” PBD
build Library “myapp_resource.pbl\myapp_resource.pbl” “” PBD
build Library “myapp_schedule.pbl\myapp_schedule.pbl” “” PBD
build Library “myapp_security.pbl\myapp_security.pbl” “” PBD
build Library “myapp_ticket.pbl\myapp_ticket.pbl” “” PBD
build Library “im_lls_rc_dws.pbl\im_lls_rc_dws.pbl” “” PBD
build Library “im_lls_rc_rpt_dws.pbl\im_lls_rc_rpt_dws.pbl” “” PBD
build Library “pies_shared.pbl\pies_shared.pbl” “” PBD
build Library “reg_01.pbl\reg_01.pbl” “” PBD

Here is how I did it in minutes of work, using NotePad++ relace with regexp:

  1. Replace step 1, this is easy, replace all \\ with \, and ‘;’ with “\n”
  2. Replace step 2, using regexp, replace all
    ^(.*)
    with
    build Library “\1″ “” PBD
  3. Done.

Notepad++ reference: http://notepad-plus.sourceforge.net/uk/regExpList.php

Sourceforge stats shown that PowerUnit has not been updated for 2years, this is wrong! I’m currently still actively playing it. The recent changes including:

  1. Using NAnt auto-build each release. The forth part of version number is subversion revision. The lattest one is 119. The subversion repository is at https://powerunit.svn.sourceforge.net/svnroot/powerunit/
  2. Display PB context version of current PBUnit. Be aware that PB context version must match with the test target. If your target is different, you need to rebuild it, either use NAnt, or in your PB IDE.pbunit_ver
  3. I am using PBScc as my current subversion client, tried PushOK for awhile, it’s OK. Comparing this PBSCC, it’s almost same as old PB dev style.
    PBSCC needs a middle area as the buffer/swap between dev machine to source repository, I think some damon process is monitoring this buffer/swap folder whenver checkin happens, then commit the changes to repo behind the scene. This left the problem of my main src folder shown un-commint-changes icon, doing a diff, the base still no showing the new changes commint through PBSCC, force a update, it said finished a merge, even the src file actually not changed at all.
    pbunit_pbscc_folderpbunit_pbscc_workspace

Problem: Any team member can deploy PB component to EAserver from PB IDE, even if they have local code not checked in, and it’s not traceable also (not in EAServer log!). We don’t know who and when touched those component on server.

We tried to put version info in the comments field of component, but it’s not guaranteed. Developer still might forget. If EAServer administrator didn’t version that point, we couldn’t rollback to certain standpoint.

Solution: Auto-deploy from CC.net build task, which is triggered by check in. Ideally should run a test project before deploy.

Similar idea from some websphere developer. We should archieve the ear file, but the orcascript alone can generate it, so call an easerver export instead.

Orcascript command:

build project PBL_NAME PROJECT_NAME SERVER_HOST PORT_NUMBER

Don’t know how to pass userid/password to this orca command. Had to add easerver profile to CC.net machine.

Ant task:

<property name="JAGUAR" value="C:\Program Files\Sybase\EAServer6\bin" />
 <target name="export_package" depends="">
 <echo message="exporting package ..." />
 <!-- <jag_export entity="Package:My_Package" /> -->
 <delete file="jar\My_Package.jar" />
 <!-- nant change executable to program -->
 <exec executable="${JAGUAR}\jagtool.bat" >
 <arg line="-server easdevSecure -host easdev -port 9100  -user jagadmin -password pass export -dir jar/ Package:My_Package" />
 </exec>
 </target>

This is for pB10.5 or later, Unicode style.


FUNCTION ulong GetFileVersionInfoSizeW  &
 ( REF string lpFilename, REF ulong lpdwHandle ) &
 LIBRARY "version.dll"

FUNCTION integer GetFileVersionInfoW &
 ( REF string lpFilename, REF ulong lpdwHandle, ulong dwLen, &
 REF string lpData )  &
 LIBRARY "version.dll"

FUNCTION boolean VerQueryValueW &
 ( REF string lpBlock, string lpSubBlock, REF long lpBuffer, &
 REF uint puLen )  &
 LIBRARY "version.dll"

SUBROUTINE CopyMemoryA &
 ( REF string d, long s, long l )  &
 LIBRARY "kernel32.dll"  &
 ALIAS FOR RtlMoveMemory

FUNCTION ulong GetModuleFileName (ulong hinstModule, ref string lpszPath, ulong cchPath )  &
 LIBRARY "KERNEL32.DLL" &
 ALIAS FOR "GetModuleFileNameA;ansi"  // ;ansi  required for PB10 or later

// function of_get_version()
ulong  dwHandle, dwLength
string ls_Buff, ls_key
uint   lui_length
long   ll_pointer
string ls_filename  
integer li_rc
string  ls_result = '?'
string ls_EXE_FILE_NAME
String ls_fullpath
ulong lul_handle, lul_length = 512

lul_handle = handle( getapplication() )

If lul_handle = 0 Then //IDE MODE
 RETURN '[IDE mode]'
End if

// running from EXE
ls_fullpath=space(lul_length)
GetModuleFilename( lul_handle, ls_fullpath, lul_length )

//ls_filename = GetCurrentDirectory ( ) + "\" + ls_EXE_FILE_NAME
ls_filename = ls_fullpath

dwLength = GetFileVersionInfoSizeW( ls_filename, dwHandle )
IF dwLength <= 0 THEN
 RETURN ls_result
END IF

ls_Buff = Space( dwLength )

li_rc = GetFileVersionInfoW( ls_filename, dwHandle, dwLength, ls_Buff )

IF li_rc = 0 THEN
 RETURN ls_result
END IF

// the strange numbers below represents the country and language
// of the version resource.
ls_key = "\StringFileInfo40904e4\FileVersion"

IF NOT VerQueryValueW( ls_buff, ls_key, ll_pointer, lui_length ) OR &
 lui_length <= 0 THEN
 ls_result = "?"
ELSE
 ls_result = Space( lui_length )
 CopyMemoryA( ls_result, ll_pointer, lui_length*2 ) // unicode
END IF

return ls_result

More to investigate:

1. How to deal with component on EAServer? Couldn’t find solution from WCF architecture. Don’t we care the version number of a remote service?

pb_dir

Ideas:

  1. Move all source file into src folder, keep pbw and pbt file in same level, otherwise PUSHOK plugin will add relative path into pbg files, which is wrong, orca will fail due to this.
  2. Add pbl into ignore list, this file keep changing and we don’t want it in repository.
  3. Create 2 build script, one for incremental build , another for full build with delete pbl, import/migrate and create exe.
  4. dist folder for distribution, should keep zip file for executable and pbls. When new member join in, after GLV from svn repository, should extra the pbl from the zip file in this folder.
  5. orca can build in offline mode, because svn will keep all the sr* file updated.
    Offline mode is only available in PB10 or above.

    start session
    scc set connect property logfile "buildfromsource.log"
    
    ;**********************************************************************
    ; connect mode
    ; read scc info from workspace
    ;**********************************************************************
    ;SCC get connect properties "pbunit.pbw"
    ;scc connect
    ;scc set target "pbunitgui.pbt"  OUTOFDATE
    ;scc refresh target migrate
    
    ;**********************************************************************
    ; offline mode
    ; sr* file should already in the src folder done by svn
    ;**********************************************************************
    scc connect offline
    scc set target "pbunitgui.pbt"  IMPORTONLY
    scc refresh target migrate  
    
    scc close
    ...build exe...
    

Tried 3 different svn clients for PB today.

  1. PBSccProxy
  2. Unified SCC
  3. PuskOK SvnSCC

I couldn’t find how to connect to a remote svn repository through PBSccProxy. Thanks to Juan, it seems PBSCC is checking in to local repository mirror folder first, then commit to remote repo. I think the IDE won’t have the out of sync flag then, need to comfirm.

Unified SCC needs me to uncheck the “Delete PB generated file” option, which made my working folder a huge mess. Also, I kept getting NullRefException when doing show diff in IDE. The readonly flag of those sr files always confused me.

PushOK is the most user-friendly one, fast, and clean. I think it doesn’t need Tortoise at all. But merge has to do through tortoise and based on sr? files, then it’s better to turn off “Delete PB generated file option”, otherwise the out-of-sync warning sign on folder will become very annoying.

Something new when using PB with SVN:

  • We can check in distributed files into repository along with source file. To do this, set the global ignore list to “*.pbl, bin/*”, then use ant task to build executable and zip the pbl moving to a “dist” folder, which can be imported into repository as a different folder. Developers just need to extract it to quickly setup the working environment.My ignore list: ” *.pbl, executable/*, *.log, *.pbc”
  • Instead of “sharing” in vss, we do “branch and merge”. Create a branch is easy, the hard part is merge back to trunk (re-integrate branch). One important thing is, there must be a working folder mapping to trunk on merging operator’s machine. Another thing shocked me is, tortoise can only do “tree merge”, which means we can only merge a “folder” back to trunk. I tried to merge one single file using Tortoise, always failed with an error said: source_url@revision must ancestrally related to dest_url@revision#”, switching back to folder/tree level merge, it passed.
  • Merge a single file from trunk to a branch is OK.

I think that’s the way it works. We should consider those cross-project files as a separated library, we don’t want just merge one single object and release. Test whole, release whole.

    <target name="build" depends="delete_last_build">
        <exec executable="orcascr9.exe" failonerror="true" >
            <arg line='/D version_nums="${year},${major},${minor},${build}" ${basedir}/build.orca' />
         </exec>        

        <antcall target="deploy" />        
    </target>

    <target name="delete_last_build">
        <delete>
            <fileset dir="${bin.dir}" includes="*.exe"  />
            <fileset dir="${bin.dir}" includes="*.pbd"  />
        </delete>
    </target>

    <target name="deploy">
        <move todir="${bin.dir}">
            <fileset dir="${basedir}/" includes="*.exe"  />
            <fileset dir="${basedir}/" includes="*.pbd"  />   
        </move>

        <antcall target="archive" />    
    </target>

    <target name="archive">
        <delete file="${dist.dir}/source.zip" />
        <delete file="${dist.dir}/executable.zip" />

        <zip destfile="${dist.dir}/source.zip"
           basedir="${basedir}"
           excludes="**/*.sr*, Executable/"
        />    

        <zip destfile="${dist.dir}/executable.zip"
           basedir="${basedir}"
           includes="Executable/"
        />
    </target>

From Sybase’s manual, OrcaScript can set version info into exe,


set exeinfo property <fileversion | fileversionnum | productversion |    productversionnum> versionString
set exeinfo property <companyname | productname | copyright | description>    propertyString

Here is a post talking about how to read this exe info from PB through API . To use this code in PB 9 or later, you should change it to ansi or GetFileVersionInfoSizeW() andGetFileVersionInfoW() API functions.

Because OrcaScript should be able to pass variable through ‘/D’ switch, but my experience is that there are some keywords you should avoid, like ‘version’ (undocumented)

My ant task to pass args.

<project name="build" default="build"
       basedir="../">

    <target name="build" depends="delete_last_build">
        <exec executable="orcascr100.exe" failonerror="true" >
            <arg line='/D version="1.2.3.4" ${basedir}/build/build.orca' />
         </exec>        

        <antcall target="deploy" />
    </target>

    <target name="delete_last_build">
        <delete>
            <fileset dir="${basedir}/Executable" includes="*.exe"  />
            <fileset dir="${basedir}/Executable" includes="*.pbd"  />
        </delete>
    </target>

    <target name="deploy">
        <move todir="${basedir}/Executable">
            <fileset dir="${basedir}/" includes="*.exe"  />
            <fileset dir="${basedir}/" includes="*.pbd"  />
        </move>
    </target>

 </project>

My orca:

start session

set lib_list = “C:\workspaces\pbunit\pb102\pbunit.pbl;”
set lib_list += “C:\workspaces\pbunit\pb102\pbunitfunc.pbl;”
set lib_list += “C:\workspaces\pbunit\pb102\pbunitui.pbl;”

set main_pbl = “C:\workspaces\pbunit\pb102\pbunitui.pbl”

;**********************************************************************
; Set up the Application
;**********************************************************************
set liblist lib_list
set application main_pbl “pbunit”

build application FULL

;**********************************************************************
; Now build the exe and PBD
;**********************************************************************

set exeinfo property companyname “Frank Mao”
; The variable name should avoid keywords, like “version”
set exeinfo property fileversion version_num
build executable “pbunit.exe” “pbunit.ico” “pbunit.pbr” “yyy”

build Library “pbunit.pbl” “” PBD
build Library “pbunitfunc.pbl” “” PBD
build Library “pbunitui.pbl” “” PBD

end session

The challenge for me is, I have to pass both fileversion and fileversionnum to orca, one is string, the other one is 4 integers. If I set version number is this way,

set exeinfo property fileversion  “7.1.0.41″
set exeinfo property fileversionnum  “7,1,0,42″
set exeinfo property productversionnum  “7,1,0,43″
set exeinfo property productversion  “7.1.0.44″

I got

pbunit_version1

Notice the one with coma being converted to dots. fileversionnum really means 4 parts of fileversionnum, must be in the format of “1,2,3,4″.

Or I can just pass the version in coma way, the File version shown on the top is in dot format, while the one in “Other version information” will still in coma way. Who cares? And how many people can tell the difference?

Strange. File version and File version number are totally different concept. They can be different.

Bruce Armstrong’s 5 years old article is still very usesful for orca users.

Spent some time on this, here is the solution.

<%
java.util.Properties props = new java.util.Properties();
props.put( “org.omg.CORBA.ORBClass”, “com.sybase.CORBA.ORB” );
org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(( String[] ) null, props );

FranksPlayGround.n_tt n_tt = FranksPlayGround.n_ttHelper.narrow( orb.string_to_object(“FranksPlayGround/n_tt”));
short a = 1;
short b = 4;
short c = 3;
short sum = n_tt.add(a, b, c);
out.println(sum);
%>

This is so called API coding style. Create PB component is nothing to say, the important part is to ‘generate stub’ at server side. (Those Helper, Holder and Operations classes in folder “EAServer\java\classes” which n_tt inherited from )

The reason I back to this is we have a project needs to get a string type of return value from EAServer. Here is what we did:

  1. Create a dst using dummy datawindow. (dst is from EAF)
  2. In createcontent event we calls a method in component.
  3. Save this return value into dst’s message, then pass it back to JSP.
  4. JSP has to do some fancy parsing to get this value out.

Seems a lot of work, but we don’t need to do ‘generate stub’ because EAF install wizard already did this for dst. We are kind like using an empty dst passing value down to JSP.

I can refactor this a little bit better by creating a seperate service object (not component) to wrap the component call.

Our current VSS works fine, but we are going to move to TFS anyway. The reasons are:

  1. VSS has no permission configuration, a developer can change any work item in source repository.
  2. VSS has no policy. Like code review before check in.
  3. VSS is slow. No real server behind.

But, the test result on TFS is good as we expected.

  1. No sharing anymore.
    We figured out Microsoft is trying to promote Branching and Merging instead of simple sharing. So our cooperation code will need 3branches at least: one for DEV, one for Acceptance, and one for Production/Release. All other projects will branch the latest version of Production/Release. Until the cooperation code is merging (for us, it’s just a deploy or copying) into the Acceptance/Production/Release branch, outside developer won’t see those unstable/untested code. Fine, I like this idea. Bye bye, sharing.
  2. Explore client.
    This is the new client for developer. If developer’s machine already has VisualStudio installed, it will become a plugin, otherwise it’s a standalone application looks like VisualStudio, but only TFS view in it.
  3. MSSCCI provider.
    It’s needed for PB developing. For orcascript, I had to modify registry to shorten the string name, because Orcascript only can handle 34 chars in SCC name. Thanks to Ronarld Smith’s post.

    scc set connect property provider “Microsoft Team Foundation Server”
    scc set connect property userid “DomainName\LoginId”
    scc set connect property project “$/ProjectName”
    scc set connect property auxproject “http://tfs-servername:portnumber”
    scc set connect property localprojpath “C:\work_dir\”
    scc set connect property logfile “buildfromsource.log”
    scc set connect property logappend false

  4. Dreamweaver.
    Doesn’t support.
  5. EClipse.
    There is a plugin develped by TeamPrise. Not free.
  6. Slow Refresh in PowerBuilder.
    It seems this is a big problem for those PB+TFS developers, for me it’s 4 times slower than VSS. Why?
  7. CC.net plugin.
    It’s available. Check the help file in CC.net.
    Watch out the wrong example there:

    <deleteWorkspace>false</workspace>
  1. Download install package from Sybase website.
  2. Install it on your planned licence server.
  3. Apply served licence for this server. When filling out the request form, port number can be ignored.
  4. Place the lic file under SySam licence folder. Launch lmtool, start server.
  5. Install client, connect to SySam server to get key.

Notes: Pb11.5 key doesn’t work for Pb11.0/1.