Welcome to the Appeon Community!

Learn, share knowledge, and get help.


Featured Blogs

Featured Articles

PowerBuilder 2017 R2 New Feature: Git source control support

In a previous blog article we looked at the new feature of PowerBuilder 2017 R2 for Subversion source control support. In this blog article we're going to look at a very similar feature, Git source control support.  I'm not going to go through the history of source code support in PowerBuilder again, I'd refer you to that previous blog article for that.  We're going dive straight in to how the Git feature works.

Setting up Git

For this demo, we're going to use Bonobo Git Server.  One reason I like it is because it provide a web based admin console for managing the server, so I don't have to use the Git command line to do that.

Because it's an ASP.Net application, the machine where we're going to install it must have IIS and the .Net Framework 4.6 installed on it.  To install Bonobo Git once you've downloaded it you simply need to:

Read more

Comments (2)

  1. Michael Kiefer

Thanks for this article; it has been helpful.

I am hoping that Appeon improves the overall experience when working with Git as there are a few things that are less than ideal.

The workarounds for cloning/specifying the URL for the repo with some very-common GIT servers are a big problem. This is particularly true since after creating a new clone manually you must "Add to source control" files that are already in source control. This creates an unnecessary commit for what is essentially a "no change" situation. This could also lead to merge conflicts on binary files.

Fortunately, I found a workaround for this extra "Add to source control" step, which is to create the appropriate registry entries manually (or write a script to do it), so that the PB UI things the code is already under source control. For example:

Windows Registry Editor Version 5.00

"Author"="My Name"

A better solution, would be for the PB UI to automatically detect that the workspace is located in a git repo and use the configuration information from the git repo directly instead of trying to maintain it separately in the registry.

I also dislike the fact that we are still storing binary files like PBLs -- particularly large ones -- in git. This is a very bad practice and leads to bad performance and huge repos. It should be possible to easily rebuild a PBL from a set of text-based source files (i.e. *.pbg, *.sr*). Unfortunately, it seems that the direction with PB2017 R3 is to go the opposite direction and eliminate the pbg files all together.

  1. Michael Kiefer

In case anyone wants the script for the above:

Function New-GitCloneForPowerBuilder { [CmdLetBinding()] Param( [Parameter(Mandatory = $true)] [string] $RepoUrl,

[Parameter(Mandatory = $true)] [string] $CloneLocation,

[Parameter(Mandatory = $true)] [string] $RelativePbwPath )

$pushedLocation = $false try { $ErrorActionPreference = 'Stop'

git clone $RepoUrl $CloneLocation $CloneLocation = Resolve-Path $CloneLocation Push-Location $CloneLocation $pushedLocation = $true

#get Git settings as set by the clone because we need to put them in the registry for PB $userEmail = git config --get user.email $userName = git config --get user.name

#Verify the workspace element exists $registryRoot = "HKCU:\Software\Sybase\PowerBuilder\17.0\Workspace" if (-not (Test-Path $registryRoot)) { New-Item -Path $registryRoot -Force| Out-Null }

#Create the specific workspace element $registryPath = $registryRoot + '\\' + ((Resolve-Path (Join-Path $CloneLocation $RelativePbwPath)) -replace '\\', '$') if (-not (Test-Path $registryPath)) { New-Item -Path $registryPath -Force | Out-Null }

$registryPath = $registryPath + '\\SourceControlVersion2' if (-not (Test-Path $registryPath)) { New-Item -Path $registryPath -Force | Out-Null }

$properties = @{ "Type" = "Git"; "Name" = ""; "ServerURL" = ""; "LocalPath" = $CloneLocation; "Author" = $userName; "email" = $userEmail; "LogAllActivity" = ""; "LogFilePath" = ""; "AppenOverWrite" = ""; "Comments" = ""; "RefreshRate" = ""; } foreach ($p in $properties.Keys) { New-ItemProperty -Path $registryPath -Name $p -Value $properties[$p] | Out-Null }

} catch { throw ("Unable to setup Git repo clone for PB workspace {0}`n{1}" -f $_.Exception.Message, $_.InvocationInfo.PositionMessage) } finally { if ($pushedLocation) { Pop-Location } } }

There are no comments posted here yet

PowerBuilder 2017 R2 New Feature: Subversion (SVN) source control support

PowerBuilder's initial support for version control systems required drivers for specific vendors (e.g., PVCS) and often for specific versions of that vendor's products.  It was not unusual to find that you needed to wait to upgrade your source control product until PowerBuilder released an updated driver for it.  And if your source control provider wasn't supported by PowerBuilder you were simply out of luck.



That changed with PowerBuilder 6.  With that release, PowerBuilder abandoned the vendor specific drivers in favor of the recently introduced Microsoft Source Code Control Interface (MSSCCI).  Essentially an ODBC for version control, it freed the IDE from vendor lock-in.  Provide the source control provide provides an MSSCCI complaint interface, or there was a 'bridge' product available that could convert MSSCCI calls into the source control providers native API calls, PowerBuilder could use the product.

Read more

Comments (4)

  1. Maurice Losier

Hi Bruce,

Great write up it did help put everything in context. I'm looking to move to R2 for the benefit of no proxy / svn. My challenge is that we have over 10 years of History origanally from CVS and migrated to SVN. I'd like to maintain history but obviously we don't have the right structure. Any opinion strategy etc. would help



  1. David Sutton

While I love the idea of a move towards a native client we will still need MSSCCI support until this native client becomes more feature complete.

Can you confirm that MSSCCI support is still functional and has not changed in R2?

  1. Bruce Armstrong

We did our migration from PVSC to SVN back in 2009, and we used the SVNImporter tool to convert over our existing repositories.


They have a version there for CVS as well. It worked quite well in our experience.


  1. Bruce Armstrong

Nothing in MSSCCI has changed.  You can still continue to use that.

I'm curious as to what features you think it's missing that are preventing you from moving to it.  Anything you can't do in the PB IDE you can still do through TortoiseSVN, it's just a tab bit more work.


There are no comments posted here yet

PowerBuilder 2017 R2 New Feature: REST

One of the new features added to PowerBuilder 2017 R2 is support for REST web services.  This feature isn't 100% complete, as additional REST functionality is planned for 2017 R3.  There's still a lot in the R2 release to look at though.

To make things simple for the demo, we're going to use a online REST web service called JSONPlaceHolder..  The service doesn't require creating an account or user authentication.  While the GET (retrieve) methods are fully functional the POST ( insert ), PUT/PATCH ( update ) and DELETE (delete) methods are placeholders.  They return result codes or in the case of POST the id value of the inserted row, but they don't actually modify the data.

Note that while REST web services can return data in any internet mime encodable format, the vast majority of them use JSON  and JSON is the only data format supported by the REST client object in PowerBuilder 2017.

Read more

Comments (5)

  1. Hani EL Dabet

Dear Mr. Armstrong,

I am trying to consume a webservice using powerbuilder 2017R2. I have consume the same service in C# and trying now to do the same in powerbuilder. I have created a WCF proxy to access the web service and able to connect. However, in order to call any function I need to add soap header for the API key.  similar to the code in c#:

 //add a soap header for API Key
MessageHeader ApiMessageHeader = MessageHeader.CreateHeader("API_KEY", "http://tempuri.org;", API_KEY);

string userName = "username";
string passWord = "xxxxxx.";
string Provider = "dsadsa";
calls the authenticate user
if the authentication is successful it will assign the token variable the appropriate value         

client.AUEAuthenticateUser(userName, passWord, Provider, ref token);


How to add soap message header in  powerbuilder before calling the method AUEAuthenticateUser.


Thanks for your reply

  1. Bruce Armstrong

Please post this question in the regular forums.

  1. Chris Pollach

Hi Bruce;

Great article .. thanks!

Just a minor point .. the JSON returned must be formed within array brackets ... for example:


"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"


  If not, the DWO data transformation will not occur.

Regards .. Chris

  1. Richard Bianco

Hi Bruce,

Enjoyed the article as I prepare for a presentation will be doing for the conference.

I'm in the (mundane) process of wiring up REST endpoints to datawindows and wanted to ask if there was anything I could do to help with coding for the REST improvements being delivered for PB2018? I'm probably re-inventing the wheel doing some of the same things you might be doing as I'm trying to write my own utility that takes an endpoint address say... https://api.binance.com/api/v1/klines?symbol=ETHBTC&;interval=1m and creating my own datawindow from the actual Json returned.

The code you have was helpful as a first step. Some changes I'd make are adding support for Json when there the Json isn't surrounded by [ ] and is only surrounded by { } .

Other things I'm trying to write into an ancestor are handling of more than two levels of hierarchy, adding support for boolean, and adding support for automatically converting numbers surrounded by double quotes to be converted to number/decimal in the datawindow. Right now I load the Json into a rough datawindow, then perform transformations on data and moving row by row to another datawindow and saving to database.

I don't have much experience with extending PowerBuilder (at internal level via PBNI) but ideally it would be cool to extend RestClient to handle some of the things I talked about. I downloaded your PBNISMTP project on GitHub and trying to figure it out. If you'd be able/willing to share that code with me- I'd be more than happy to provide enhancements made so you can decide if you want to incorporate them into the tool. I would be honored to think that some of my code made it into the actual release and would expect no compensation. Though if you want to hire me as consultant I'd work for a very reasonable rate (for PB developer).

You should have access to my email via the site but will post it here anyway as this page is member only: rich@displacedguy.com or displacedguy@gmail.com I'm not the best about responding quickly but would really appreciate a response. I have some time and can surely help with any work you have.

p.s I'm also working on a wizard type window that I provide REST endpoint address (like above) and parse the Json into datawindow allowing me to set column name, data type, etc., with as much info derived as possible. Also I'd add ability to generate a database table to store result and have ideas on defining the Json fragments (complex object types) into my database so the definition of Json is data driven. Yeah I have a lot on my plate but it's fun.

Rich Bianco

  Comment was last edited about 2 days ago by Richard Bianco Richard Bianco

I don't know about the feasibility if this could really cover all situations of automatically creating the DataWindow from the endpoint, but boy if you could do that it would be so cool and save time!

There are no comments posted here yet


Con los nuevos sistemas una de las cosas que hoy en día escuchamos es: tenemos un web services donde puedes consultar…

Por lo que ante esta necesidad y teniendo un sistema desarrollado originalmente en powerbuilder 6.5 ( les traigo esta solución.

Un “consumer” de WS REST

Para hacer este ejemplo utilizaremos objetos no visuales, principalmente el objeto internetresult.

Read more

Comments (2)

  1. miguel riveros

where it comesthe object  lib_json.

I get an error trying to create the visual interfase:

Error C0001 Illegal data type: lib_json

Undefined variable: json

Please help where I should do corrections to the example code 


  1. Alfredo Aldama


You can comment this lines

With this you should retrieve since Web service

The lines commented above is for parse, and show in datawindow

There are no comments posted here yet

Most Popular Articles

Exporting Datawindows to Excel / Html without loosing Format

I have a function called "GuardarAExcel2()" which uses a step datawindow called "d_filafichero". With this function you generate an excel with the same visual aspect as your datawindow. I hope it helps you:

Example of use:

GuardarAExcel2( dw_1, "c:\Report.xls")
GuardarAExcel2( dw_1, "c:\Report.html")

Result in datawindow:


Read more

Comments (15)

  1. Byron Guaman

Hola Eduardo G, intento ejecutar tu funcion pero falta el objeto ds_datastore, puedes publicarlo por favor para probar tu funcion saludos.

  1. Eduardo G.

Hola Byron, ds_datastore (UserObject) está heredado de datastore, puedes reemplazarlo por lo siguiente:

Hello Byron, ds_datastore (UserObject) is inherited from datastore, you can replace it with the following:

datastore dsHTML
dsHTML = CREATE datastore
dsHTML.DataObject = "d_FilaFichero"
dsHTML.ImportFile( Text!, spRuta )

Un saludo.

  1. jhon sparky

hello eduardo G,

it's work for me..but all border in cell not view..still loosing format..

  1. Leonardo Velazquez

Hola.... muchas gracias por el aporte.... en Chrome se ve muy bien... pero en Excel me divide en 2 renglones cada registro.... 


  1. Eduardo G.

Te ocurre debido a que los objetos column que tienes en el detail no deben de estar a la misma altura o tienes alguno superpuesto a otro. Es muy aconsejable que los objetos no estén uno encima del otro para que funcione correctamente.

Un saludo.


Hello. Hi,
It happens to you because the column objects you have in the detail must not be at the same height or you have some superimposed to another. It is highly advisable that the objects are not on top of each other for them to function properly.
A greeting.


Buenos dias amigo me sale error en la funcion F_global_replace .

podrias especificar el tipo de valor y sus argumentos. Gracias es muy importante poner a prueba tu funcion 

  1. Eduardo G.




Argument Type >> Argument Name

string >> source

string >> look_for

string >> replace_with

Return Type string


A String Occurrence Search and Replace Routine

The following code demonstrates a string occurrence search and replace routine.

This routine works generically for any string. For example, 

if old_str = "red" and new_str = "green", all occurrences of 

 "red" inside of mystring will be replaced with "green".


int start_pos=1,len_look_for

len_look_for = len(look_for)


//find the first occurrence of look_for ...

start_pos = Pos(source,look_for,start_pos)

//only enter the loop if you find whats in look_for

DO WHILE start_pos > 0

//replace look_for with replace_with ...

source = Replace(source,start_pos,Len_look_for,replace_with)

//find the next occurrence of look_for

start_pos = Pos(source,look_for,start_pos+Len(replace_with))


return source





// Función: f_cuenta_char

// Descripción: Cuenta todas las ocurrencias de as_char en  la cadena as_source

// Ambito: publica

// Argumentos: as_source {cadena de la que se desea borrar las ocurrencias de as_char}

//    as_char   {caracter a ser contado de la cadena as_source}

// Retorna: Integer {numero de ocurrencias encontradas}


int li_pos

int ncuenta=0


li_pos = Pos (as_source, as_char, 1)

do while li_pos > 0


as_source = Left (as_source, li_pos - 1) + &

Right (as_source, Len (as_source) - li_pos)

li_pos = Pos (as_source, as_char, 1)



return ncuenta

  1. Eduardo G.

Ya lo tienes :-D

  1. Ivan Mesarc

Hello, it does not respect custome date format for datetime columns. Could you help please?


  1. Eduardo G.

Hello, check the block "// Prevent text with / convert to date" to adapt it to your needs.
A greeting.

There are no comments posted here yet

Using PowerBuilder 2017 with TFS source control

This article is a guide to connect Powerbuilder 2017 with TFS. It is important to follow the steps in the order listed in the article.

The prerequisite includes

  • PB17 installed on a local machine.
  • TFS server running with access to the user. A collection is required where the code will be checked in. 

Next follow the below points:

  1. Team explorer 2013 : Yes the first thing needed is to install Visual studio team explorer. I know the first question pop ups in mind is if Visual studio needs to be installed on every machine !! Well the answer is NO. All you need is Team explorer 2013 to access the TFS. Second question is why 2013 ? Well there comes the 32 bit and 64 bit compatibility issues, moreover there is no standalone installer for Team explorer 2015. If you figured out a way to do it with later versions, then mention it in the comments. 
Read more

Comments (7)

  1. Frank Frey

Nice article. Would this also be applicable to PB12.6 classic?

  1. Nasir Ahmad

Yes, It should work for 12.6 classic version and 12.5 as well. 

  1. Vollie Sanders Jr

Question I have is what TFS server version do we need to use, Corp office has TFS2010 and TFS2015. will ether of these work?


Frank, I am writing a similar document for PB 12.6 with TFS2017 (server), using VS2015. I hope to share it soon. My initial recommendation for you, is to create a folder for each PBL.

  1. Nasir Ahmad

TFS2015 server will work as per my knowledge since MSSCCI and team explorer i tested was for TFS 2013, which worked for TFS 2017.  

For earlier versions of TFS you test and find MSSCCI, Team explorer which are compatible with that version. 

  1. Van Sederburg

Worked perfectly!

  1. Armeen Mazda

Another way to use PB 2017 with TFS is to switch the repository from the legacy TFVC to Git. With recent versions of TFS the default repository is actually Git, and Microsoft recently acquired GitHub. The advantage of switching is that PB 2017 natively interfaces with Git rather than using the legacy MSSCCI interface, which gets you support for more source control features and faster performance of source control operations.

There are no comments posted here yet

The ClassDefinition Object (Part 1)

The ClassDefinition object was introduced in PowerBuilder 6.0 a long time ago. It allows you to retrieve information for an object at runtime. Most of us didn't pay too much attention to this object and it only attracts our attention when we see it in the debugger.

In this article I provide an overview of the ClassDefinition object and related objects and explain the most important properties of these objects. I also include a step-by-step guide on how to build a simple object browser. This browser has a limited functionality like the browser included in the PowerBuilder runtime environment and can't replace products like PBLPeeper by Terry Voth or PBBrowser by OOWidgets.

The ClassDefinition Object Hierarchy
The classdefinitionobject is a descendant of the pbtocppobject. It's the ancestor of all the other objects used to describe the PowerBuilder objects. Each object in PowerBuilder has one property named ClassDefinition that references the ClassDefinition of this object.

Read more

Comments (0)

There are no comments posted here yet

Refactoring Classic PowerBuilder Applications Using TDD and pbUnit

The migration march to PB 12.NET will have many shops revisiting legacy applications. In my previous article, "Refactoring Is Not an ‘R' Word" (PBDJ, Vol. 16, issue 12), you read why refactoring code before migration helps ensure smooth migration and enterprise integration. You were introduced to Test Driven Development methodology and saw how you can use it to ensure successful refactoring. You were also introduced to pbUnit, an open source tool and framework that you can use for both refactoring and developing new code in PB Classic applications. In this article I'll guide you through installing pbUnit and help you master the basic algorithm when refactoring your PB legacy code with pbUnit and test driven methodology.

Installing pbUnit and Configuring Your App: The Nuts and Bolts
In addition to installing and using pbUnit with Classic PowerBuilder to run unit Tests, you'll also learn how to get your code under test so you can go about refactoring your code with confidence. After that, I'll show you how to do a couple of refactorings to thin out a GUI and partition business and data logic

Now is the time to take that old code and whip it into shape. You suspect that unit test drive development has some merit and would like to try it out. This article will show you how to get started.

There are a couple of ways you can get your hands on pbUnit. You can download a PB v10.2 version from the Sybase CodeXchange. This version will migrate without error to version 10.5, 11.x or 12.0 Classic. Point your browser to http://www.sybase.com/developer/codexchange, then proceed to the PowerBuilder section and find pbUnit. You'll want to take version 3.2. Alternatively, if you want me know that you're trying out TDD, you can drop me an email and I'll send you a zip with a PB 12.0 compatible version. I didn't change the doc since I didn't make any changes to the code. I upped the version number on my zip to 3.3 to indicate the change.

Read more

Comments (0)

There are no comments posted here yet

That worked well for some time.  However, the source control landscape has changed significantly since then.  In particular, open source version control systems dominate the market now, primarily Subversion (SVN) and Git.  Fortunately for PowerBuilder users, there are 'bridge' products out there for those source control systems, but they have some limitations or are not well supported.

In order to address those issues, Appeon introduced native support for Subversion and Git in PowerBuilder 2017 R2.  We're going to look at using the new Subversion support in this article.

Setting up Subversion

For this demo I'm going to use VisualSVN for the Subversion server.  I like that particular product because it provides a GUI server manager, saving me from having to manage the server via command prompt.

Also, because the PowerBuilder IDE currently doesn't support a full set of the SVN options (e.g., show log, repo browser, etc.) I'm going to install TortoiseSVN in order to use those features.  Once again I could use the subversion command line client to do this, but I prefer having the options available to me through a GUI, in this case Windows Explorer.

Creating a Repository

Using the VisualSVN Admin tool, just right click on the Repositories and select "Create New Repository..."

On the first page of the dialog, select the default "Regular FSDS repository" option and click Next.

In the second page of the dialog, give the repository a name and click Next.

In the third page of the dialog, select the non-default "Single project repository" option and click Next.

In the fourth (and last) page of the dialog, select "All Subversion user have Read/Write access" option and click Create.

You'll also need to create a user account.  Right click on Users and select "Create User..."

In the dialog that appears, enter the user name, the password and then confirm the password.

This is just for demo purposes.  In actual practice you might want to consider using the Windows Authentication capability of Visual SVN instead for user authentication.

Go back to the the repository you created, right click on it in the admin tool and select the "Copy URL to Clipboard" option.

Add the PowerBuilder Project to the Subversion Repository

With Subversion we're going to take a different approach to connecting the PowerBuilder workspace to the source control than we have in the past with MSSCCI based interfaces.  Instead of going to workspace properties and selecting the Source Control tab, we're going to right click on the workspace and select the "Add to Source Control..." option.

That brings up a dialog in which you can select either Subversion (SVN) or Git.  Select Subversion (SVN) and then click OK.

In the next dialog, past in the SVN repository URL you copied when you created the repository.  Also provide your user ID and password for the subversion server.

On the next dialog simply click OK.

Now let's examine what PowerBuilder did in the VisualSVN admin tool:

If you're familiar with how source control worked from PowerBuilder using MSSCCI you'll note a couple of significant differences in how it's handled under Subversion.

1.  Instead of extracting the source code for the PowerBuilder objects into the same directory as the PBLs and then checking them in from there, PowerBuilder created a ws_objects folder (I assume ws stands for workspace), created a folder for each PBL underneath that then exported the source from each PBL into it's respective folder.  With MSSCCI based source control it was standard practice to put each PBL into a different directory to ensure there were no collisions if two objects in two different PBLs happened to have the same name.  When Subversion is used for source control, PowerBuilder handles that for us and we can leave the main PBLs all the in same folder.

2.  Under MSSCCI, only the target file and the exported source code was checked into source control.  This was a problem when you a developer needed to get connected to a new (to them) project.  Since the PBLs weren't checked into source control the developer would either need to get a set of PBLs from another developer or create the PBLs from the checked out source.  Under Subversion PowerBuilder checks in the workspace file and all the PBLs as well.  As we will see in a minute, that makes it very simple to get started with a new project.

Note that after you're connected to Subversion, Subversion does show up under the Source Control folder in the workspace properties.  This allows you to see and in some cases edit the connection information.

Download the Repository into a New Workspace

In a bit, we're going to emulate two different developers working with the same project, and so we're going to "check-out" the project we just added to source control into a different workspace.  Close the current workspace, and then select File -> Connect to Workspace.

In the dialog that appears we'll give it the same repository URL we used when we added the source code to the repository.  I've created a second user id that I'll be using for the multi-developer emulation later, and I'll use that user id here.  Finally, make sure that the Checkout Directory is a different directory than the directory for the original workspace.

And viola!  We've got the entire workspace, PBLs and all.

Making Source Code Changes

Here's another area where there is a large departure between how source control is handled via MSSCCI and via Subversion.  Under MSSCCI, you needed to check out an object (obtaining a lock on it) before you could make changes to it and save them back to source control.

When Subversion is used for source control, PowerBuilder will mark an object with a check mark when the developer has made changes to an object and they have not committed yet.  With MSSCCII that meant the file was locked.  With Subversion only means the object has been modified from what is in source control.  Other developers are not prohibited from making changes.to the same object.  Let's see what happens when that occurs.

Let's say we go into one workspace and change the background color of a window to red.  Now lets go into the second workspace and change the title of the same window.  Go ahead and commit the change to the title.

Now let's go back to the first workspace and attempt to commit our change there.  It's not quite as obvious as it could be, but the commit fails.  The reason is that the object has been modified in source control since we started editing it.  The output pane shows "Target file is out of date."  That's the indication that we need to do an update to get the already committed change.

So we select SVN Update from the popup menu on the object.  We should see an indication in the output pane that the update was successful.

It also notes however that there was a merge conflict.  If you look at the system treeview, the object in question has a yellow exclamation in front of it now indicating that it's in a merge conflict status.

When a merge conflict happens, Subversion creates a number of different files n the source control folder.  In this case, where we modified an object called w_main, we find the following:

  • w_main.srw - The object with just the second developer's changes
  • w_main.srw.r{oldrev} - The object as it existed in the second developer's workspace before they started editing it.
  • w_main.srw.r{newrev} - The object that was checked in by the first developer.

{oldrev} and {newrev} aren't literal the they're the subversion checkin revision numbers.

At this point, PowerBuilder still won't let us commit the change to the background color.  What we need to first is review the changes and indicate what should be accepted.  That's one of the reasons I recommend installing TortoiseSVN.  Open up Windows Explorer, navigate to the object in question under the ws_objects folder, right click on it and select TortoiseSVN->Edit Conflicts

That will bring up the following editor.  Indicate which changes you want to include in the final object and then hit "Mark as Resolved".

At that point, the files with the {oldrev} and {newrev} file extensions have been deleted.  Go back into the PowerBuilder IDE and do a Refresh on the object that had the conflict.

The icon changes back to a check mark, indicating that we are now free to commit the merged changes.

One problem with reviewing edits in text mode is that the PowerBuilder IDE in some circumstances will modify the order that functions, events, etc. occur in the source code.  Most merge tools, such as the one provided by default in TortoiseSVN, don't handle source code that has had blocks of code moved well.  For example, this is what that merge tool showed when I deleted and added empty functions in an object.

Note that the merge tool doesn't recognize that the first function was dropped, instead it thinks I renamed the method.  Once it makes that mistake, the rest of the file (assuming the functions had code in them) would result in huge, false, merge differences.

Fortunately there are merge tools out there that do handle source code where blocks of code have been moved.  One such example is SemanticMerge.  When run on that same sample, SemanticMerge fully recognized which functions were dropped and which were added.

What was particularly impressive here is that SemanticMerge doesn't have a parser that understand PowerScript.  Instead, it treated it as a simple text file.  However, it also has an external parser API so that end users (you and I) can define a parser that does handle PowerScript and even further improve how it works when doing merges.

Avoiding Merge Conflicts

Because merge conflicts require manual editing of the source code as text, it's best to avoid them completely if possible.

Unlike MSSCCI, PowerBuilder doesn't indicate on a Refresh under Subversion whether or not your local objects are in sync with the source control system.  Therefore, one of the primary things you can do to avoid merge conflicts is ensure that your workspace is update to date with source control by doing an SVN Update before making changes to an object.  Otherwise you may experience a merge conflict just because you based your edit on an out of date object.

Another option is, after making sure the object is up-to-date, obtaining a lock on it.  Like MSSCCI, there is a lock option on the Subversion menu:

However, it isn't implemented yet.  Instead, you'll get this notice indicating how you can lock the file until it is.

So, it's back to TorroiseSVN.  Go back to the object in the ws_objects folder, right click on it, and select TortoiseSVN->Get lock.

After you've locked the file it will display with a lock folder in Windows Explorer, but the PowerBuilder IDE current doesn't display any change, even after a refresh.  If you see a file that displays the lock symbol and want to know who has it locked, you can use the TortoiseSVN->Repro-browser option to see more information about the file.

One interesting feature of Subversion, different from MSSCCI, is that you have the ability to "break" or "steal" locks.

This becomes quite helpful if a developer checks out an object, forgets about it, and leaves for vacation for 2 weeks.  If you need to work on the object while they're gone you can simply break the lock and lock it yourself.  The developer who left on vacation will then have to merge once they're back and ready to commit their changes.

Now lets see what happens when another user attempts to edit the object.  They can, but when they attempt to commit they get this error in the output pane.

It would be better if the second developer knew in advance that another user had already locked the file.  One way to ensure that is to have the developers learn the habit of locking the file before they attempt to make any edits.

One way that would normally ensure they learn that habit is by applying the Subversion svn:needs-lock property on the PowerBuilder objects under source control.  That property automatically marks the source code files as read only unless the developer has a lock on the file.  Unfortunately, PowerBuilder 2017 (at least R2) overwrites the file anyway and allows the user to commit without the lock.

In the event that gets resolved when R3 supports locking, you could even consider automatically applying the property to your PowerBuilder source code.  Prior to Subversion 1.8, the best way to do that was through a pre-commit hook that applied the property as files were commited.  Subversion introduced the svn:auto-prop property, which makes it even simpler.


The Subversion interface provided in PowerBuilder 2017 R2 eliminates the need to use bridge products through the MSSCCI interface to allow PowerBuilder to use Subversion for source control.  Because it works natively with Subversion rather that going through a bridge, it is faster and eventually will provide more complete Subversion support.  Subversion though does bring a bit more complexity to the development experience, particularly dealing with merge conflicts.

Comments (4)

  1. Maurice Losier

Hi Bruce,

Great write up it did help put everything in context. I'm looking to move to R2 for the benefit of no proxy / svn. My challenge is that we have over 10 years of History origanally from CVS and migrated to SVN. I'd like to maintain history but obviously we don't have the right structure. Any opinion strategy etc. would help



  1. David Sutton

While I love the idea of a move towards a native client we will still need MSSCCI support until this native client becomes more feature complete.

Can you confirm that MSSCCI support is still functional and has not changed in R2?

  1. Bruce Armstrong

We did our migration from PVSC to SVN back in 2009, and we used the SVNImporter tool to convert over our existing repositories.


They have a version there for CVS as well. It worked quite well in our experience.


  1. Bruce Armstrong

Nothing in MSSCCI has changed.  You can still continue to use that.

I'm curious as to what features you think it's missing that are preventing you from moving to it.  Anything you can't do in the PB IDE you can still do through TortoiseSVN, it's just a tab bit more work.


There are no comments posted here yet