1. paulo gomes
  2. SnapObjects
  3. Wednesday, 10 July 2019 19:50 PM UTC

Hi all,

We are evaluating the efforts to migrate PB NVOs from an EAS web app to REST API using Snap Develop and PB 2019.

We already migrated few methods using the IDataStore object. However we noticed that several methods were missing from the original PB datastore as follows:

1. Describe

2. Modify

3. ClassName

4. Error and DB Error events

5. SelectRow

6. setItemStatus

7. generateResultSet from a datastore

8. createFrom (rSet)

The web App is more than 12 years old and shares several NVO with an even older Client App. Both Apps extensible use the methods mentioned above.

We also noticed that the transaction object SQLCA is not part of any Snap Develop class. This fact is a big inhibitor since the mentioned Apps use SQLCA after every DB access to check if it was successful and, if not, get the error code and text.

Imagine how many times SQLCA is referenced in an enterprise App with more than 2 million lines of Power Script.

Migrate to C# an enormous App is itself a big task and it will be even worse if we have to introduce C# code that does not belong to the original PB code, increasing the chances to add logical errors to a code that works.

Workarounds to wrap code like IF SQLCA.SQLCODE < 0 THEN  in a Try/Catch block is sometimes difficult to accomplish due to the way the PB code was written, long time ago.

SQLCA is affected after any DB access, not only by datawindow/datastore retrieve/update methods but also by SQL embedded code, which we also have a lot, making things more complex.

We would like to know if someone already faced these challenges or knows what is Appeon's approach for these concerns.

Thank you in advance,

Paulo Gomes


Interval International

Senior PB Analyst


Ricardo Jasso Accepted Answer Pending Moderation
  1. Monday, 15 July 2019 19:35 PM UTC
  2. SnapObjects
  3. # 1


I've been reading Appeon's promotional material and following an example of the C# Web API "migration" solution and I came to the following conclusions:

PowerBuilder 2019 does not provide an automatic migration solution nor an easy port tool to migrate non-visual objects to C#. The only thing that can be automatically ported right now is the data object part of a DataWindow or DataStore (not the visual control object part) to a ModelStore equivalent.

This means that only properties mapping the original data object's columns are created in a C# class to be used by the new .NET DataStore class. Get/Set methods are created automatically. A big step but only one part of a complete migration solution. What this helps us to do is to quickly cloudify our PowerBuilder applications by changing direct database access to REST Web APIs calls, but this does not mean that we have migrated our business logic to C# Web APIs.

PowerBuilder 2019 provides a .NET equivalent to the DataWindow/DataStore control object which can be used in C# projects. Nevertheless, there is no automatic port of the PowerScript code which might have been added to a user DataWindow/DataStore control, so this must be done manually. The same can be said about non-visual objects that may or may not use DataWindow/DataStore controls as part of its logic. All this must be ported manually (aka re-write).

I think Appeon could help users like you who have a lot invested in EAServer and like me who see how current PB web services deployment options are getting discontinued by developing automatic migration tools from PowerScript to C# and/or consider reviving the concept of a proprietary application/web server based on PowerBuilder technology to directly deploy our PowerBuilder assets as web APIs, like what EAServer was used for.





  1. Armeen Mazda @Appeon
  2. Monday, 15 July 2019 20:40 PM UTC
Hi Ricardo, I guess you have not looked at the PB roadmap and so you do not know our plans. In revision of PB 2019 we have plans to introduce an automatic PowerScript-to-C# converter: https://www.appeon.com/developers/roadmap

  1. Helpful
  1. paulo gomes
  2. Monday, 15 July 2019 20:50 PM UTC
Hi Ricardo,

Thank you for your comments. Yes, re-write an app from ground-up having to "face" million of lines of power script and embedded SQL, even having the data objects converted to reusable C# classes, is a big task.

We already got rid of EA Server via .Net SOAP web services target and .Net Assembly target ( DLL ), both deployed into IIS. We have in Production a hybrid environment.

We had to refactor the PB code to be exposed to receive simple data types (non datastore nor result sets). After the refactor, PB 12.0 did it with 100% of automation. However, both solutions proved not to be the ideal solution:

1. The SOAP web service is too slow due to hundred of thousand of internal calls between the PBDs; a simple login generates more than 150,000 "not coded" io to disk, monitored during sessions by our IIS tech people

2. The .Net assembly DLL is way faster then the SOAP web service but it is not thread-safe, so data get corrupted in a multi-thread environment, like IIS. To make it work I had to write a C Sharp web service to be invoked from the Client (Java front-end) to create a queue of requests and then load balancing the queue to attend the requests one by one, in a single-thread fashion.

We are now evaluating the efforts needed to migrate to REST Web API using Snap Develop classes but so far we found it very time consuming and prone to re-code logic errors (see my comments about SQLCA as example in the blog).

On top of that there is the C Sharp learning curve for the PB professionals thta vener had contact with C Sharp before.

Appeon Tutorials are well prepared and help to understand this new .Net Core 2.0 architecture and there are good videos in the You Tube.

Thank you for the comments.

Paulo Gomes

Senior Analyst

Interval International


  1. Helpful
There are no comments made yet.
Logan Liu @Appeon Accepted Answer Pending Moderation
  1. Friday, 12 July 2019 08:32 AM UTC
  2. SnapObjects
  3. # 2

Hi Paulo,

As far as I know, what Appeon is doing now is to try to provide a translation tool to batch translate the code of the PB project into the C# Web API project, and the translated C# code should have a higher standard of maintainability.

However, this tool focuses on solving the problem of about 80% of the workload, it can greatly reduce the workload of migration, but the developer still needs to do a lot of things to complete the migration.

1. Describe/ Modify

A migration-specific extension library is being considered to support these traditional PB methods during the migration process, including possibly Describe/Modify methods. In an ideal situation, the newly developed application can use the current standard library. You can use these traditional PB methods by simply referencing this extension library during migration.


For your example:

Icount = integer(ads.describe('DataWindow.Column.Count'))"

It can be changed to object style:

Int icount = dataStore.Object.DataWindow.Table.Columns.Count;

Note that the current structure of the .NET DataObject's properties, which is now closer to the structure in  DataWindow Syntax, is a little different from the native PB.


For your computed field creation example:

dataStore.Modify("Create" + " " + Syntax)

It can be changed to:


It will parse this line and add a new Compute Field to Computes. You can then access it as an object or modify it.


2. Error handing events and SQLCA

I also understand that SQLCA is really hard for migration. Appeon also needs to analyze the feasibility of extending similar functionality on the DataContext, and if possible, I think it might be available as an extension library.

In addition, we can also look forward to the future translation tool can make the migration of SQLCA related code easier.


3. SyntaxFromSQL

SyntaxFromSQL is mostly used in UI-related dynamic scenarios. At the same time it is also low performance. Appeon is considering a better solution about the dynamic creation of a .NET DataStore from SQL.

The .Net DataStore does not provide the UI related functionality, However, Appeon is considering adding a new object (maybe called .Net DataWindow) in the next phase that may include the SyntaxFromSQL function.

If you only do dynamic queries based on SQL, it is recommended to use the SqlExecutor method to achieve similar functions.




  1. paulo gomes
  2. Friday, 12 July 2019 15:45 PM UTC
Hi Logan,

These are really good news !

We are aware that just translating PS to C# we eventually will be missing some best practices for robust coding and maintainability.

We are also sure that Appeon is trying it's best to help.

A migration-specific extension library sounds a good idea to me and it should accomplish most of the needs.

As I mentioned before, we are already working to evaluate the efforts needed to migrate and I may have few more items to post here in the near future on the evaluation path.

We have "lots" of code with all kind of different situations so please let me know if you need some "snipes" as example.

Thank you for your reply.

Best regards,


Senior System Analyst , Interval International - Since October 2007

Resort Solution Development IT Team

6262 Sunset Drive • Miami, Florida 33143

Phones: 305.666.1861, ext. 7393 • direct 305.925.7393 Fax:305.668.3409

  1. Helpful
There are no comments made yet.
paulo gomes Accepted Answer Pending Moderation
  1. Thursday, 11 July 2019 18:00 PM UTC
  2. SnapObjects
  3. # 3

Hi Logan, thank you for the reply. 

I understand your points of view. However we have more than 2 million lines of code to migrate to C# and any code added that does not belong to the original PB code could lead to extra migrating time and lead to introduce errors in a code that works today.

We are still evaluating the time to accomplish the task.

I see as major trouble the lack of the Describe/Modify, error handling events and the SQLCA:


Per your request, an example of Describe as it is in our App follows:

- in a NVO method the datastore ads is passed as argument and the number of columns is evaluated by the statement "icount = integer(ads.describe('DataWindow.Column.Count'))"

Another situation is to create a computed field at run time in a datastore with different expressions, depending of several factors. Then the Describe is used to get what is there. The Modify is eventually used to replace the original definition with other string.

Following your suggestion, I'll take a look into the C# Evaluate method.

Error handling events and SQLCA

I developed for Interval a very large web services in C# years ago and it uses Try/Catch blocks to handle the errors. This web service successfully invokes several PB NVOs and returns JSON to the caller. 

The trouble is not the use of Try/Catch blocks. The trouble is to add to the REST C# API pieces of code that do not belong to the original power script code, changing the original logic and making the API code prone to errors.

Also as you know, the events "Error" and "DB Error" are "triggered" when an error occurs and the SQLCA holds the information about the error.

If we do not have the corresponding events in C#, a new error handling design has to be in place before we start the migration. Whatever the new design is, for an App this size it represents "lots" of lines of code to be added, and this is a big problem. 


Inspecting our use of SQLCA, I found a lot of code that uses the SyntaxeFromSQL method of SQLCA, which I did not mention it before. Do you have any comments about it?

Thank you.


Senior System Analyst , Interval International - Since October 2007

Resort Solution Development IT Team

6262 Sunset Drive • Miami, Florida 33143

Phones: 305.666.1861, ext. 7393 • direct 305.925.7393   Fax:305.668.3409




There are no comments made yet.
Logan Liu @Appeon Accepted Answer Pending Moderation
  1. Thursday, 11 July 2019 06:40 AM UTC
  2. SnapObjects
  3. # 4

Hi Paulo,
When migrating PB project to C# Web API project, we need to consider not only the convenience of the migration process, but also whether the migrated program benefits from C# and NET Core, and whether the stability of the code on the server is guaranteed and highly maintainable.

1. Describe/Modify
This method is not available because the use of string expressions is more consuming on the server side and it’s also less maintainable.
If you can provide an example, we can analyze and see if we can find a better migrating solution.
(Note the Evaluate method is already provided by the .NET DataStore)

2. ClassName
You can use the .NET method to get the class name.

3. Error and DB Error events / SQLCA.SQLCODE question
It is recommended to use the Try catch method to catch exceptions.
PB's original way of handling database exceptions is prone to write wrong code without throwing exceptions. If we swallow the exception, all relevant useful information we can extract from the debug exception will be lost, and we haven't done anything to recover from this anomaly.
The server program should be stable, and it is recommended to throw the exception when there is an exception.

4. SelectRow
This is a UI-related method, which is irrelevant on the server side.

5. SetItemStatus
This method has been split into two methods in .NET DataStore: SetItemStatus and SetRowStatus.

6. GenerateResultSet from a datastore / createFrom (rSet)
You can use the recommended JSON for exchanging data.
Refer to ExportJson/ExportPlainJson methods.


There are no comments made yet.
  • Page :
  • 1

There are no replies made for this question yet.
However, you are not allowed to reply to this question.