DataWindow Syntax Updater
DataWindow Syntax Updater
A DataWindow's source (.srd) keeps the release n; line and syntax format of the PowerBuilder version that last saved it in the DataWindow painter. Migrating to a newer version, a full build, PBAutoBuild, PBC and ORCA all compile that source without rewriting it, so old DataWindows stay at release 5, 6, 12.5 and so on until someone opens and saves each one in the painter.
This utility does the painter's part for a whole folder at once. For each .srd file it:
- Loads the source into the DataWindow engine (
DataStore.Create). - Asks the engine for the syntax back (
Describe("DataWindow.Syntax")). The engine always writes the current release, with every property written out, so nothing depends on the old release's defaults. - Puts the initial data back in (
Describe("DataWindow.Syntax.Data")), sinceDataWindow.Syntaxleaves it out. - Checks the result: it must load, describe the same objects and hold the same number of initial rows as the original. If it doesn't, the file is left alone and logged as failed.
- Writes the file back with the same encoding, line endings and any lines that came before
release(//objectcomments,$PBExportHeader$).
Files that are already at the current release aren't touched.
Requirements
- PowerBuilder 2025 R2 (runtime 25.1.0.6430) to build, and that runtime to run. The release it writes is the one for the runtime it runs under, so build it with the PowerBuilder version you're moving to.
- DataWindow source as files on disk: a PowerBuilder solution (
.pblfolders), or.srdfiles exported from a workspace. PBL files from a workspace aren't read directly; export, convert, and import them, or move to the solution format first.
Building
Open DWSyntaxUpdater.pbsln in the IDE and deploy p_dwsyntaxupdater_exe, or from the command line:
pbautobuild250.exe /pbc /d DWSyntaxUpdater.pbproj /o dwsyntaxupdater.exe /f /x 64
Usage
dwsyntaxupdater [folder] [/out=folder] [/log=file] [/dryrun] [/force] [/quiet]
| Option | Meaning |
|---|---|
folder |
The folder to scan, with its subfolders. Folders whose names start with . (.git, .pb) are skipped. When left out, you're asked for one. |
/out=folder |
Write converted files here, keeping their relative paths, instead of replacing them. It can't be inside the source folder. Only converted files are written. |
/log=file |
The log file. Defaults to dwsyntaxupdater.log in the current folder. |
/dryrun |
Report what would be converted without writing any files. |
/force |
Rewrite files that are already at the current release. |
/quiet |
Show no messages, for use in scripts; results go to the log only. |
Each file gets one log line: CONVERTED (with the old and new release), CURRENT or FAILED (with the reason). A WARNING line follows files that need a second look. A summary ends the log.
Samples
samples holds 15 unconverted DataWindows from PFC 2025: releases 5 to 22, including some with initial data, nested reports and drop-down DataWindows. To see what a conversion does, run the utility on them and look at the diff:
dwsyntaxupdater.exe samples
git diff samples
git checkout -- samples
The last command puts the samples back the way they were.
Before converting a code base
- Run it on a branch, or on a clean working copy, so you can review the diff and revert.
- Expect a large diff. The engine writes every property out and orders them its own way, so even an unchanged DataWindow gains many lines.
- The output is the engine's syntax, which the painter writes in its own order and line wrapping. They describe the same DataWindow, but the text won't match a painter save byte for byte. Saving a file in the painter afterwards will reorder it again.
- DataWindows with nested reports get a warning. Their
dataobjectreferences and arguments are kept, but open one or two in the painter to confirm. - Build and run the application after converting.
Tested on
PFC 2025's 164 DataWindows (releases 5 to 22, eight of them with initial data, three with nested reports): all converted to release 25, a second run found them all current, and a project built from the converted DataWindows compiled cleanly.
License
DataWindow Syntax Updater is released under the MIT License; see LICENSE.txt. The DataWindows in samples come from the PowerBuilder Foundation Classes and are covered by PFC's own MIT License, in samples/LICENSE.txt.
https://github.com/bruce-armstrong/DataWindowSyntaxUpdater
This message has an attachment file.
Please log in or register to see it.
Last Edit: 2 weeks 3 days ago by Bruce Armstrong .
Please Log in or Create an account to join the conversation.
Hi Bruce,
Thanks for the offer! I've opened an issue with all the details: github.com/bruce-armstrong/DataWindowSyntaxUpdater/issues/1
The 8 original DataWindows belong to a private ERP, so I can't share them. I've uploaded a ZIP in a separate comment on the GitHub issue, and I'm sharing it here as well. It contains minimal, made-up DataWindows that reproduce the same behaviour, along with examples of what the utility currently writes and what it should write.
In short: when a sort (either in a table or in a group) calls a global function that the engine can't resolve, Describe("DataWindow.Syntax") writes the sort back mangled (memory garbage in a group sort, an extra "A" in the table sort), and the validation check doesn't catch it.
We worked around this by replacing those sort keys with string-literal markers, converting the DataWindows, and then restoring the original text.
The issue also covers a random "describes different objects" failure caused by the obj_<n> names the engine assigns to unnamed objects.
Regards,
Ramón
This message has an attachment file.
Please log in or register to see it.
Please Log in or Create an account to join the conversation.
If you wouldn't mind zipping up those 8 failing datawindows and attaching them to an issue on the github repo I could see about updating the utility to handle them correctly. That wouldnt help you out as you've already dealt with it, but it will help ensure it works better for other in the future.
Please Log in or Create an account to join the conversation.
Hi Bruce,
Thanks for this, and for releasing it under MIT. Letting the DataWindow engine rewrite the syntax itself, instead of
just changing the release line, is the right idea. It saved us a lot of guesswork.
We ran it on our ERP: 1,777 DataWindows across 14 different releases, 1,604 of them needing the update. One case is
worth reporting: a sort that calls a global function, in the table or in a group, either directly or through a
computed field. The engine doesn't have the application's libraries, so it can't resolve the function and rewrites the
sort wrongly. You get memory garbage in the group sort (@SP@Get_Describe, random characters, even the path of the
host library), … A A, or the key dropped from the table sort. The updater writes these files without a warning. We
had 8 of them.
Our workaround: when we detect it, we convert again with every sort key that isn't a column replaced by a text marker
('__pbdw_k0__'). The engine copies the marker through untouched, and then we put the original expression back in its
place and flag the file with a warning. We tried a global function in 31 different places (filter, computes, ~t
expressions, validation, group by=, graphs, crosstab, nested reports, treeview), and only sort breaks. To check the
result, we built a .pbd with stub functions of the same signatures so the engine could resolve them: all 1,602
converted DataWindows came out byte-for-byte identical. Two limits:
- If the DataWindow has initial data, we don't apply the workaround (the marker would reorder the rows) and report the
file as failed.
- As a safety net, we reject any result where the number of function calls inside quoted values changes.
We've built this into pbAID, a small PowerBuilder IDE I'm working on that runs in the browser. It's written in Python,
not PowerScript:
- A Python process loads the PowerBuilder 64-bit runtime through PBNI.
- It opens a session against a tiny embedded host .pbd (CreateSession needs a library with an application object).
- It calls DataStore.Create, Describe("DataWindow.Syntax") and Describe("DataWindow.Syntax.Data") directly, the same
steps as your utility, working in batches.
The engine doesn't write any files. pbAID writes each converted .srd itself, keeping the original encoding, re-reading
it to verify, and restoring the original byte for byte if anything doesn't match. The target release is the one of
the runtime the project declares in its application object. In the IDE you reach it in three ways:
- right-click on a solution, a library or a single DataWindow;
- when migrating a project to a newer runtime;
- from a "DataWindows by release" report.
After converting, it runs a full build to confirm everything still compiles. Your 15 samples come out byte-for-byte
identical to dwsyntaxupdater.exe, which we use as the reference in our tests.
Thanks again for sharing it.
Ramón
Please Log in or Create an account to join the conversation.