Open Menu

Synergex Blog


CodeGen 5.1.4 Released

By Steve Ives, Posted on July 29, 2016 at 10:42 am

We are pleased to announce that we have just released CodeGen V5.1.4. The main change in this version is an alteration to the way that CodeGen maps Synergy time fields, i.e. TM4 (HHMM) and TM6 (HHMMSS) fields, to corresponding SQL data types via the <FIELD_SQLTYPE> field loop expansion token. Previously these fields would be mapped to DECIMAL(4) and DECIMAL(6) fields, resulting in time fields being exposed as simple integer values in an underlying database. With this change it is now possible to correctly export time data to relational databases.

We also made a small change to the CodeGen installation so that the changes that it makes to the system PATH environment variable occur immediately after the installation completes, meaning that it is no longer necessary to reboot the system after installing CodeGen on a system for the first time.

This version of CodeGen is built with Synergy/DE 10.3.3a and requires a minimum Synergy runtime version of 10.1.1.


Replicating Data to SQL Server – Made Easy

By Steve Ives, Posted on July 28, 2016 at 5:29 pm

For some time now we have published various examples of how to replicate ISAM data to a relational database such as SQL Server in near to real time. Until now however, all of these examples have required that the ISAM files that were to be replicated needed be modified by the addition of a new “replication key” field and the addition of a corresponding key in the file. Generally this new field and key would be populated with a timestamp value that was unique to each record in the file. While this technique guarantees that every ISAM file can be replicated, it also made it hard work to do so because the record layout and key configuration of each ISAM file needed to be changed.

However, almost all ISAM files already have at least one unique key, and when that is the case one of those existing those keys could be used to achieve replication without requiring changes to the original record layouts or files. When this technique is combined with the capabilities of I/O hooks it is now possible to achieve data replication with only minimal effort, often with no changes to the ISAM files being replicated, and with only minimal modification of the original application code.

I am pleased to announce that I have just published a new example of doing exactly that. You can find the example code on GitHub at https://github.com/SteveIves/SqlReplicationIoHooks. Of course if you are interested in implementing data replication to a relational database but need some assistance in doing so, then we’re here to help; just contact your Synergex account manager for further information.


Symphony Framework Update 3.2.6 – File Management Capabilities

By Richard Morris, Posted on July 22, 2016 at 6:24 am

As I wrote about in my last blog the Symphony Harmony namespace provides the ability to execute select queries and stored procedure style method execution using SQL style syntax. The queries and procedures can be executed in-process or via the Symphony Bridge on a remote server via industry standard HTTP/HTTPS/TCP protocols as well as via a Service Bus Relay protocol. In the 3.2.6 release we have added the ability to fully manage the data in the SDBMS files via SQL this style syntax.

Accessing or selecting data through the Symphony Harmony namespace is simple. First you need to define your “connection” to the database. To do this you create an instance of the DBConnector class. For example;

data connector = new DBConnector(“SymLocal:user/password!SimpleHarmonyTestLibrary.TableMapper.MapTableToFile”)

The connection string defines how you want to access the data: SymLocal indicates that it’s in-process and specifying SymRemote indicates it’s via Symphony Bridge. If you are using Symphony Bridge you must include the “server” you wish to connect to – I’ll include an example shortly. The username and password allow you to provide authentication but that’s for another blog. The “SimpleHarmonyTestLibrary.TableMapper.MapTableToFile” is the named method that Symphony Harmony uses to translate the table name to a physical SDBMS filename, and it’s something you can code generate.

Here is an example of a remote access connection;

data connector = new DBConnector(“SymRemote:user/password@localhost:8081!SimpleHarmonyTestLibrary.TableMapper.MapTableToFile”)

Notice the server name and the port the Symphony Bridge server is listening on. Other than the connection string the usage of Symphony Harmony is identical regardless if it’s local or remote data access. Although here we are talking about local and remote data access – we are referring to where the code to perform the query is being executed, either locally in-process or via Symphony Bridge. We are not referring to the physical location of the SDBMS data files which may be local or remote and accessed via xfServer. Both local (in-process) and remote connections via Symphony Bridge can access data locally or via xfServer.

To select records from a file you use the SQL style SELECT syntax and call the DataSelect.RunDataSelect method. You need to instance the Symphony Data Object that will define the response data structure. For example;

data partItem = new Part_Data()

foreach partItem in DataSelect.RunDataSelect(connector, “SELECT * FROM part”, partItem).Result

begin

                Console.WriteLine(“Created ID = ” + partItem.Id + “, ” + partItem.Description + ” Qty = ” + %string(partItem.Quantity) + ” Cost = ” + %string(partItem.Cost_price))

end

Note here that the case of the command is not important however the case of string values within a where clause is. You can limit the fields returned, filter the data and order the results as you require. All of these are valid;

DataSelect.RunDataSelect(connector, “SELECT id, description, quantity FROM part WHERE quantity > 10”, partItem).Result

DataSelect.RunDataSelect(connector, “SELECT description, id FROM part WHERE description like ‘BRAKE’”, partItem).Result

DataSelect.RunDataSelect(connector, “SELECT cost_price, id, description FROM part WHERE cost_price < 1.99 ORDER BY cost_price “, partItem).Result

The order of the fields list is not important. You also don’t have to hard-wire the filter values as you can pass positional arguments. For example;

Data qtyValue   ,int         ,10

DataSelect.RunDataSelect(connector, “SELECT id, quantity, description FROM part WHERE quantity > :1”, partItem, qtyValue).Result

data descValue ,string   ,”BRAKE”

DataSelect.RunDataSelect(connector, “SELECT id, description FROM part WHERE description like :1″, partItem, descValue).Result

Data qtyValue   ,int                         ,10

Data costValue  ,decimal               ,1.99

DataSelect.RunDataSelect(connector, “SELECT id, description, cost_price FROM part WHERE cost_price < :1 AND quantity > :2 ORDER BY cost_price “, partItem, costValue, qtyValue).Result

All of the above will return a collection of data objects of type Part_Data().

As I mentioned above you can now maintain the data in your SDBMS files through Symphony Harmony. We have added the ability to insert data into an SDBMS file using Symphony Harmony. The DataInsert.RunDataInsert() method accepts an INSERT command and a data object and stores the passed-in data object data to the appropriate file. For example;

data partItem = new Part_Data()

partItem.Id = “ID1”

partItem.Description = “this is the description for part 1”

partItem.Technical_info = “lots of additional information for part 1”

partItem.Quantity = 5

partItem.Cost_price = 12.34

DataInsert.RunDataInsert(connector, “INSERT INTO part”, partItem).Wait()

The data in the partItem data object is extracted, placed into a Synergy record and stored into the SDBMS file. Any errors, like duplicate key, will be thrown on the client.

We have also added the ability to update the data in an SDBMS file using Symphony Harmony. The DataUpdate.RunDataUpdate() method accepts an UPDATE command, which should include a WHERE clause, and a data object, and updates the file with the passed data object data. You can optionally pass a list of fields that restrict the data to be updated. So for example if you application wants to simply update a field for a given record;

data numUpdated          ,long

partItem.Cost_price = 999.99

numUpdated = DataUpdate.RunDataUpdate(connector, “UPDATE part SET cost_price where QUANTITY = 13”, partItem).Result

Will update ALL records that have a quantity value of 13 with the updated cost_price value of 999.99. The resulting numUpdated field will contain the number of records that were updated in the file.

The field list is optional, but it’s recommended! If you don’t specify the field list then the whole record is updated, so you must ensure that the data object contains all the required information otherwise you may get exceptions if key values that are defined none-modifiable are changed. You may also inadvertently overwrite changes made by other processes.

And to provide the fully SDBMS data management capabilities we have added the ability to delete data from an SDBMS file using Symphony Harmony. The DataDelete.RunDataDelete() method accepts a DELETE command, which should include a WHERE clause, and a data object and deletes the matching records from the file.

data numDeleted            ,long

numDeleted = DataDelete.RunDataDelete(connector, “DELETE FROM part WHERE id = :1”, partItem, “ID1”).Result

Removes the required records from the file. There is no need to first select or lock them. The numDeleted field will contain the number of records that were deleted from the file. The where clause is optional so the following is valid;

numDeleted = DataDelete.RunDataDelete(connector, “DELETE FROM part”, partItem).Result

And will result in clearing the entire file – you have been warned!!

All this capability is now available in version 3.2.6 of the Symphony Framework, Symphony Harmony and Symphony Harmony Unplugged packages on Nuget.


Merging Data and Forms with the PSG PDF API

By Steve Ives, Posted on July 6, 2016 at 9:53 pm

When I introduced the PSG PDF API during the recent DevPartner Conference in Washington DC I received several questions about whether it was possible to define the layout of something like a standard form using one PDF file, and then simply merge in data in order to create another PDF file. I also received some suggestions about how this might be done, and I am pleased to report that one of those suggestions panned out into a workable solution, at least on the Windows platform.

The solution involves the use of a third-party product named PDFtk Pro. The bad news is that this one isn’t open source and neither is it free. But the good news is it only costs US$ 3.99, which I figured wouldn’t be a problem if you need the functionality that it provides.

Once you have PDFtk Pro installed and in your PATH you can then call the new SetBackgroundFile method on your PdfFile object, specifying the name of the existing PDF file to use as the page background for the pages in the PDF file that you are currently creating. All that actually happens is when you subsequently save your PDF file, by calling one of the Print, Preview or Save methods, the code executes a PDFtk Pro command that merges your PDF file with the background file that you specified earlier. Here’s an example of what the code looks like:

;;Create an instance of the PdfFile class
pdf = new PdfFile()

;;Name the other PDF file that defines page background content
if (!pdf.SetBackgroundFile(“FORMS:DeliveryTicketForm.pdf”,errorMessage)
    throw new Exception(errorMessage)

;;Other code to define the content of the PDF file

 

;;Show the results
pdf.Preview()

There are several possible benefits of using this approach, not least of which is the potential for a significant reduction in processing overhead when creating complex forms. Another tangible benefit will be the ability to create background forms and other documents using any Windows application that can create print output; Microsoft Word or Excel for example. Remember that in Windows 10 Microsoft has included the “Print to PDF” option, so now any Windows application that can create print output can be used to create PDF background documents.

I have re-worked the existing Delivery Ticket example that is distributed with the PDF API so that it first creates a “form” in one PDF file, then creates a second PDF file containing an actual delivery ticket with data, using the form created earlier as a page background.

I have just checked the code changes into the GitHub repository so this new feature is available for use right away, and I am looking forward to receiving any feedback that you may have. I will of course continue to research possible ways of doing this on the other platforms (Unix, Linux and OpenVMS) but for now at least we have a solution for the Windows platform that most of us are using.


Symphony takes a REST

By Richard Morris, Posted on at 3:08 am

The Symphony Harmony namespace allows access to data and logic through an SQL like syntax. For example you can select records from a file using a query such as “SELECT ID, DESCRIPTION FROM PART WHERE QUANTITY > 12 ORDER BY QUANTITY”. All matching records are returned from the query in the form of Symphony Data Objects. The data can be local or accessed via Synergy xfServer. The Symphony Bridge utility allows you to expose your query-able database via a standard Windows Communication Foundation (WCF) web service. So far so good.

Steve Ives and I recently had the opportunity to spend a week working together in the UK to “bang” heads together. Steve has always been an exponent of providing RESTful services to access logic and data which can be consumed by just about anything. So we set about using CodeGen to build a standard Restful service that will utilize the Symphony Framework to enable dynamic access to data and ultimately logic.

We soon had the basic service up and running. Out first implementation handled the standard GET verb – and returned all the records in the file. No filtering, no selection, just all the records retuned as a JSON collection. This is the standard API;

rest_1

Now remember that Symphony Harmony allows you to filter the data you are requesting, so we next implemented the ability to provide the “where” clause to the query. So for example;

rest_2

And using ARC (Advanced Rest Client which is a Google Chrome plug-in) we can test and query the service;

rest_3

And we get back just the selected customer details – all those customers where CUSTST has value of CA.

As well as being able to filter the data we can also limit the results returned by Harmony to just the fields we need; this has the benefit of reducing the data being brought across the wire. But how can our REST server build the required data objects to just include the fields we select? By doing runtime code generation! Within our code generated data objects we added the ability to dynamically build the response data object to only include those fields requested by the client. The calling syntax, as provided by the API, is;

rest_4

And again using ARC to test our server we can issue a command like;

rest_5

This is requesting all records from CUSMAS where the CUSNM2 field contains the word “LAWN” and limiting the response data object to just three fields. The response JSON looks like;

rest_6

Two perfectly formed data object that are limited by the fields in the selection list. If your Symphony Harmony connection to your data is via xfServer then only those selected fields will have been loaded from the file, again improving performance.

We also added the ability to limit the amount of data retuned by adding a “maxrows” option;

rest_7

We have already added the ability to the Symphony Harmony namespace to perform inserts, updates and deletes using standard SQL syntax and we’ll be adding these capabilities to the appropriate rest verbs POST, PUT and DELETE. Watch this blog feed for more information.


RSS

Subscribe to the RSS Feed!

Recent Posts Categories Tag Cloud Archives