Symphony Framework
SymphonyFramework Assembly

The Symphony Framework is a powerful set of libraries and utilities that provide software developers with a number of opportunities to enhance and expand their .NET applications. 

 Symphony Conductor
       

The Conductor namespace is the powerhouse of the Symphony Framework. Key features include the ISAM thread-safe data access layer, Windows Presentation Foundation (WPF) visual state navigation control, thread management utilities, Data type conversion capabilities, and the Symphony Data Object. This is the central component of the Symphony Framework providing a number of key features including:

  • Symphony Data Object. The Data Object is at the core of the Symphony Framework. It provides the connection between your application data and the outside world. Although the name may suggest it, a Data Object has no concept of the source of the data it is holding and exposing. The programmer may load the data from a file, database, memory, or a remote web service – the data object simply exposes it. The Data Object is code generated from a repository structure but is not just a wrapper for the data as it provides a lot of additional functionality, for example:
    • Performs field level data validation as per the rules defined in the repository. Required fields are validated, ranged values are checked. The Data Object also provides hooks that allow you to perform additional validation as the data is changing.
    • Provides object validation. The Data Object provides properties that indicate the status of the Data Object. The IsDataValid property indicates of all the data within the object is valid – passes the standard repository validation and any custom validation. The IsDataModified indicates if the data has been modified from its original state. IsNew is a property that indicates the Data Object is new and has no data within it.
    • Each data field defined in your repository structure is exposed as a read/write property. The base Data Object class implements the INotifyPropertyChanged interface so that any consuming client will be able to react to changes to the data. This is a standard across WPF, Universal Windows Platform (UWP), and device application using Xamarin Forms.
    • Associated with each data field from the repository structure, the class also exposes IsReadOnly and IsEnabled properties that allow you application to control the editable state of the data within your Data Object. Methods within the Data Object allow you to simulate the set processing techniques within the UI Toolkit to change the states of individual fields, all fields, or sets of fields.
    • An additional HasFocus property for each data field allows your host program to request focus to a field within an edit form. The User Interface (UI) portion of your application can be written to honor these requests and move field focus as required. A user interface built using Symphony Styles implements this focus change capability.
    • If defined in the repository, the Data Object will also provide properties that allow access to additional static information such as:
      • Field heading – the report headings defined for each field in the repository structure.                 
    • Implements the IComparable (defines a generalized type-specific comparison method that a value type or class implements to order or sort its instances) methods that allow the Data Object instances to be sorted. The .NET Framework is unaware of Synergy types such as Alpha, Implied Decimal, etc. so the Data Object provides the ability to sort on these unknown types.
  • Thread safe processing. The .NET Framework bring with it the ability to perform multiple tasks simultaneously on different threads within your applications process space. Elements of the core application environment – such as data file access (local and remote) – require protection against cross thread operations. The Symphony Framework provides a number of classes that ensure complete thread safe operation.
 Symphony Core

The Symphony Core namespace provides the ability to manage logging actions and events within your application to the Symphony Event Log

 Symphony.dB

The Symphony.dB namespace provide powerful relational database capabilities to your existing business applications.  Using the Symphony.dB namespace you can easily migrate your existing ISAM file based data access routines to powerful relational database management capabilities. The Symphony.dB namespace also provides you with powerful data-replication capabilities.

Symphony.dB supports PostgreSQL, Microsoft SQL Server, MySQL and Oracle databases.  Symphony.dB is also royalty free.

To easily replace your ISAM file based access with Symphny.dB to manage your data in one of the supported relational databases you can use the following as a guide.  RCP Consultants can assist with your migration from ISAM to relational database data management.

The Symphony.dB environment uses code-generated structure specific database management routines to map the data from your application "record" area to column based structured data.  Once these have been created you can utilise them to enable your application to manage the data in your chosen database.

 

The first step is to create an instance of the Symphony.dB DBAccess class. 

    database = new DBAccess("example", "DBMANAGER:DatabaseManager")

To open the "data table" as you would an ISAM file, use the OpenUpdate() or OpenInput() methods;

    error_flag = database.OpenUpdate(channel)

for update mode, or;

    error_flag = database.OpenInput(channel)

For input mode.  Once the "table" has been opened then you can manage the data within the table.  To read the data you can perform various functions, for example;

    error_flag = database.Find(keyValue, D_PRIMARY)
    error_flag = database.ReadFirst(keyOfRef, dataArea)
    error_flag = database.Read(keyValue, keyOfRef, dataArea)

You can store and update data in the table;

    error_flag = database.Store(dataArea)
    error_flag = database.Write(dataArea)

And to delete data from the table;

    error_flag = database.Delete()

The same rules apply as when processing data in an ISAM file - you must, for example, read a record from the table before you can update (Write()) or delete (Delete()) it.  The same "No-Current-Record" errors will be returned if not.

 

In addition to the standard ISAM style operations you can also query the database using Select style operations.  To perform a "select" query you could use the following example;

    itemDatabase = new dbAccess("item", "DBMANAGER:DatabaseManager")
    itemWhereClause = new WheredB()
    itemWhereClause.Add("code", WheredBConditions.StartsWith, %atrim(code_filters.code_filter))
    itemOrderBy = new OrderBydB("code")
    foreach itemAsString in itemDatabase.Select("code, description, status, def_source_type", itemWhereClause, itemOrderBy)
    begin
        item_list = itemAsString
    end

If your application uses generic file handling routines to access your flat ISAM data files the Symphony.dB framework provides a number of methods that can be used to easily migrate that code to accessing data in a relational database.  You can also migrate files one at a time without the need to convert the entire application database.

For example you can modify your generic "file open" routine to check for a specific fie and manage the data in the database for the file;

    if (%instr(1, internalFileName, "USERID.ISM"))
    begin
        ;;we are using PostgreSQL so let's open the table on the the file!
        error = Symphony.dB.DBAccess.GenericFileOpen(chan, file, mode)
        xreturn
    end

Now your "channel" references a database table and not a flat ISAM file you can perform the required operations on the data.  The generic routine used to read data, for example, could be changed as such;

    ;;Check if we are accessing data from a database
    if (Symphony.dB.DBAccess.GenericDBCheck(channel))
    begin
        keyNumber = 0
        if (^passed(key_no)) then
            ;;use the passed key number
            keyNumber = key_no
        else
            ;;find the key number given the key value
            keyNumber = Symphony.dB.DBAccess.GenericFileKeyCheck(channel, ^argtype(key), ^size(key))
        ;;read the "row" from the database
        err = Symphony.dB.DBAccess.GenericFileRead(channel, key, keyNumber, record)
        xreturn
    end

To store data, use;

    ;;Check if we are accessing data from a database
     if (Symphony.dB.DBAccess.GenericDBCheck(channel))
    begin
    
        ;;store the record data to the database table.
        error = Symphony.dB.DBAccess.GenericFileStore(channel, record)
        xreturn
    end

To update data use;

    ;;Check if we are accessing data from a database
    if (Symphony.dB.DBAccess.GenericDBCheck(channel))
    begin
        if(%passed(err))clear err
        error_no = Symphony.dB.DBAccess.GenericFileWrite(channel, record)
        if(%passed(err)) err = error_no
        xreturn
    end

and to delete data from the database table use;

    ;;check to see if this "Channel" is a database channel and not an ISAM channel
    if (Symphony.dB.DBAccess.GenericDBCheck(channel))
    begin
        err = Symphony.dB.DBAccess.GenericFileDelete(channel)
        xreturn
    end

The application code which uses your generic file processing routines does not need to change and continues to process the data in the same way.

 

 

 Symphony Harmony and Symphony Bridge

Symphony Harmony takes the basic concept of the Symphony Data Object and wraps it with the ability access data and logic in an SQL based fashion on a remote server. Industry standard protocols are used to enable client server connections in both in LAN and WAN environments.

Enabling logic and data access on your application server from a device or browser is a fundamental requirement for any application. The Symphony Harmony and Symphony Bridge namespaces empower the developer to continue to harness the power of their existing business logic on these portable/distributed devices. Utilizing standard HTTP/HTTPS communication protocols, Windows Communication Foundation (WCF) and RESTful web services the Symphony Bridge service provides access to application logic and data using Symphony Data Objects.

Symphony Harmony is a namespace that manages data and logic execution via Symphony Bridge. The Harmony namespace provides methods to perform standard data manipulation tasks such as select, insert, update, and delete. It also provides access to remote logic using an SQL stored procedure structured implementation.

Security in today's distributed computing environment is of paramount importance. The Symphony Bridge employs standard HTTP and secure HTTPS protocols to enable communication between client and server. Additional levels of security have been built into the Bridge server—methods must be attributed to prevent malicious execution of none-attributed logic.

Migrating application logic from a procedural, process-based application brings with it several considerations including the use of common and global data, hard-wired channel numbers and none thread-safe xfServer data access. In a multi-threaded environment this can cause a multitude of problems. The Symphony Bridge Server addresses all of these issues by encapsulating the execution of the logic into application domains and managed threads.

Via Symphony Bridge, the Symphony Harmony namespace uses Symphony Data Objects to communicate data between client and server. Application repository based Data Objects can be passed to the server, along with standard Common Language Runtime (CLR) types. All methods return a collection of Data Objects.

To enable complex data elements the code generated repository structure Data Objects can be extended to include both individual and collections of other data objects. This allows a single method on the server to return a collection of complex Data Objects. For example, a collection of order headers and associated order line items for each header together with extended supplier and product details. This extensibility is a powerful way of communicating data between client and server.

The Symphony Bridge is a pre-built Windows Service so there are no requirements on the developer to understand and develop server programs, methods or protocols. Develop a class, implement the required methods, and apply the required security attribute and place the resulting assembly in the required folder is all that is required.

A physical or virtual machine can execute multiple Bridge servers and each can be configured independently.

Namespaces
NamespaceDescription
 
 

The Symphony.Conductor.Commands namespace contains a number of powerful commanding classes to provide quick and easy data-binding between user interface commands and application logic.

Symphony Framework provide a number of collection types that provide thread safe access to collection data.  The Content namespace provides additional classes to manage in a thread-safe way simple collections that can be data-bound to UI components like selection/drop-down combo boxes.

The Symphony.Conductor.Framework namespace contains a number of classes that enable easier development of your WPF desktop applications.  The UIStateStack, for example, enables the ability to provide visual environment processing.  The VMMessenger class provides the ability to communicate messages between the different elements of your WPF Desktop application.

The Model namespace contains the base classes for the Symphony DataObject.

 
 
 
 
 
 
 

The Symphony.dB namespace provide powerful relational database capabilities to your existing business applications.  Using the Symphony.dB namespace you can easily migrate your existing ISAM file based data access routines to powerful relational database management capabilities. The Symphony.dB namespace also provides you with powerful data-replication capabilities.

Symphony.dB supports PostgreSQL, Microsoft SQL Server, MySQL and Oracle databases.  Symphony.dB is also royalty free.

To easily replace your ISAM file based access with Symphny.dB to manage your data in one of the supported relational databases you can use the following as a guide.  RCP Consultants can assist with your migration from ISAM to relational database data management.

The Symphony.dB environment uses code-generated structure specific database management routines to map the data from your application "record" area to column based structured data.  Once these have been created you can utilise them to enable your application to manage the data in your chosen database.

 

The first step is to create an instance of the Symphony.dB DBAccess class. 

    database = new DBAccess("example", "DBMANAGER:DatabaseManager")

To open the "data table" as you would an ISAM file, use the OpenUpdate() or OpenInput() methods;

    error_flag = database.OpenUpdate(channel)

for update mode, or;

    error_flag = database.OpenInput(channel)

For input mode.  Once the "table" has been opened then you can manage the data within the table.  To read the data you can perform various functions, for example;

    error_flag = database.Find(keyValue, D_PRIMARY)
    error_flag = database.ReadFirst(keyOfRef, dataArea)
    error_flag = database.Read(keyValue, keyOfRef, dataArea)

You can store and update data in the table;

    error_flag = database.Store(dataArea)
    error_flag = database.Write(dataArea)

And to delete data from the table;

    error_flag = database.Delete()

The same rules apply as when processing data in an ISAM file - you must, for example, read a record from the table before you can update (Write()) or delete (Delete()) it.  The same "No-Current-Record" errors will be returned if not.

 

In addition to the standard ISAM style operations you can also query the database using Select style operations.  To perform a "select" query you could use the following example;

    itemDatabase = new dbAccess("item", "DBMANAGER:DatabaseManager")
    itemWhereClause = new WheredB()
    itemWhereClause.Add("code", WheredBConditions.StartsWith, %atrim(code_filters.code_filter))
    itemOrderBy = new OrderBydB("code")
    foreach itemAsString in itemDatabase.Select("code, description, status, def_source_type", itemWhereClause, itemOrderBy)
    begin
        item_list = itemAsString
    end

If your application uses generic file handling routines to access your flat ISAM data files the Symphony.dB framework provides a number of methods that can be used to easily migrate that code to accessing data in a relational database.  You can also migrate files one at a time without the need to convert the entire application database.

For example you can modify your generic "file open" routine to check for a specific fie and manage the data in the database for the file;

    if (%instr(1, internalFileName, "USERID.ISM"))
    begin
        ;;we are using PostgreSQL so let's open the table on the the file!
        error = Symphony.dB.DBAccess.GenericFileOpen(chan, file, mode)
        xreturn
    end

Now your "channel" references a database table and not a flat ISAM file you can perform the required operations on the data.  The generic routine used to read data, for example, could be changed as such;

    ;;Check if we are accessing data from a database
    if (Symphony.dB.DBAccess.GenericDBCheck(channel))
    begin
        keyNumber = 0
        if (^passed(key_no)) then
            ;;use the passed key number
            keyNumber = key_no
        else
            ;;find the key number given the key value
            keyNumber = Symphony.dB.DBAccess.GenericFileKeyCheck(channel, ^argtype(key), ^size(key))
        ;;read the "row" from the database
        err = Symphony.dB.DBAccess.GenericFileRead(channel, key, keyNumber, record)
        xreturn
    end

To store data, use;

    ;;Check if we are accessing data from a database
     if (Symphony.dB.DBAccess.GenericDBCheck(channel))
    begin
    
        ;;store the record data to the database table.
        error = Symphony.dB.DBAccess.GenericFileStore(channel, record)
        xreturn
    end

To update data use;

    ;;Check if we are accessing data from a database
    if (Symphony.dB.DBAccess.GenericDBCheck(channel))
    begin
        if(%passed(err))clear err
        error_no = Symphony.dB.DBAccess.GenericFileWrite(channel, record)
        if(%passed(err)) err = error_no
        xreturn
    end

and to delete data from the database table use;

    ;;check to see if this "Channel" is a database channel and not an ISAM channel
    if (Symphony.dB.DBAccess.GenericDBCheck(channel))
    begin
        err = Symphony.dB.DBAccess.GenericFileDelete(channel)
        xreturn
    end

The application code which uses your generic file processing routines does not need to change and continues to process the data in the same way.

 

 

 
 

Symphony Harmony is a powerful library that allows SQL like access to your Synergy DBMS data and Synergy .Net logic.  The classes within Symphony Harmony can be used to access data and logical both locally (in-process) or remotely via Symphony Bridge.  The syntax and calling structure is identical regardless.

Symphony Harmony uses Symphony Data Object$ classes to communicate data using standard SQL like query command and stored procedures (methods).  These classes should be code generated and included in a class Library.  The class library should then be referenced in the client project (local access) or placed ion the Symphony BRidge folder for remote access.  In addition to the data object classes the framework requires a table mapping routine to line the table name defines in the commands to the physical Synergy DBMS file name.  This table mapping method can be code-generated using the Symphony_TableMapping template.