Data Aquarium Framework

Labels
AJAX(112) App Studio(7) Apple(1) Application Builder(245) Application Factory(207) ASP.NET(95) ASP.NET 3.5(45) ASP.NET Code Generator(72) ASP.NET Membership(28) Azure(18) Barcode(2) Barcodes(3) BLOB(18) Business Rules(1) Business Rules/Logic(140) BYOD(13) Caching(2) Calendar(5) Charts(29) Cloud(14) Cloud On Time(2) Cloud On Time for Windows 7(2) Code Generator(54) Collaboration(11) command line(1) Conflict Detection(1) Content Management System(12) COT Tools for Excel(26) CRUD(1) Custom Actions(1) Data Aquarium Framework(122) Data Sheet(9) Data Sources(22) Database Lookups(50) Deployment(22) Designer(177) Device(1) DotNetNuke(12) EASE(20) Email(6) Features(101) Firebird(1) Form Builder(14) Globalization and Localization(6) How To(1) Hypermedia(2) Inline Editing(1) Installation(5) JavaScript(20) Kiosk(1) Low Code(3) Mac(1) Many-To-Many(4) Maps(6) Master/Detail(36) Microservices(4) Mobile(63) Mode Builder(3) Model Builder(3) MySQL(10) Native Apps(5) News(18) OAuth(8) OAuth Scopes(1) OAuth2(11) Offline(20) Offline Apps(4) Offline Sync(5) Oracle(10) PKCE(2) PostgreSQL(2) PWA(2) QR codes(2) Rapid Application Development(5) Reading Pane(2) Release Notes(180) Reports(48) REST(29) RESTful(29) RESTful Workshop(15) RFID tags(1) SaaS(7) Security(80) SharePoint(12) SPA(6) SQL Anywhere(3) SQL Server(26) SSO(1) Stored Procedure(4) Teamwork(15) Tips and Tricks(87) Tools for Excel(2) Touch UI(93) Transactions(5) Tutorials(183) Universal Windows Platform(3) User Interface(338) Video Tutorial(37) Web 2.0(100) Web App Generator(101) Web Application Generator(607) Web Form Builder(40) Web.Config(9) Workflow(28)
Archive
Blog
Data Aquarium Framework
Saturday, August 16, 2014PrintSubscribe
Sending Emails with SQL Business Rules

Email business rules offer a simple and effective mechanism of creating email notifications for various workflow tasks. For example, a simple notification can be sent out when a new customer account is created. Another example is a notification with attached PDF reports triggered by an update of a product category record.

An email business rule is a static text-based template with placeholders matched to a data controller action command name and execution phase. The template may also include XML-based attachment instructions. A single email notification is generated by application framework when an email business rule is matched to a command activated by application user. Template placeholders are replaced with the field values of the affected data row. If the multiple selection mode is enabled, then a separate notification is generated for each selected data row. Here is an email business rule that produces a notification with two attachments for Categories controller.

An email business rule selected in Project Designer of Code OnTime app generator.

The text of the email business rule script template is shown next. The data value placeholders are highlighted.

Host: smtp.gmail.com
Port: 587
UserName: YOUR_EMAIL_ADDRESS@gmail.com
Password: PASSWORD
EnableSSL: true

From: "Sales Admin" <your_email_address@gmail.com>
To: RECIPIENT@northwind.com
Subject: Category "{CategoryName}" has changed!

Dear Admin,

This product category has been changed.
See attachment for category product details.

System Monitor

<attachment type="report">
    <name>{CategoryName}</name>
    <controller>Categories</controller>
    <view>editForm1</view>
    <filter>
        <item>
            <field>CategoryID</field>
            <operator>=</operator>
            <value>{CategoryID}</value>
        </item>
    </filter>
</attachment>
<attachment type="report">
    <name>{CategoryName} Products</name>
    <controller>Products</controller>
    <sortExpression>UnitPrice desc</sortExpression>
    <filter>
        <item>
            <field>CategoryID</field>
            <operator>=</operator>
            <value type="Int32">{CategoryID}</value>
        </item>
    </filter>
</attachment>

If a specific notification cannot be expressed with a static text template, then consider using SQL business rules to compose an email by writing notification text in the programming language of the database engine.  Database programming languages, such as T-SQL of Microsoft SQL Server, offer enough flexibility to compose a notification of any complexity.

SQL business rules are text-based scripts executed by the database engine. The scripts may include references to data controller fields, properties of BusinessRules class associated with the data controller, URL arguments, and session variables. Developers reference any of these resources as parameters that do not have to be explicitly declared in the scripts.

Application framework binds these “pre-defined” parameters to the corresponding resources, executes the script, collects the output parameter values, and ignores any datasets that may have been produced when the script was executed.

A special mechanism exists in the application framework to force it to pay attention to the output of the SQL business rule script. The developer must supply two business rules that are matched to the same command. The first business rule triggers the “awareness” mode of the application framework. The second business rule produces a dataset that will be captured by the framework. Application framework copies the output data to an instance of System.Data.DataTable class and assigns it to BusinessRules.EmailMessages property. The property implementation iterates over the data table rows and treats each row as a notification that must be sent out. The column names of the table, such as “Port”, “To”, “From”, “Subject”, and “Body” allow the framework to compose correct email messages. The message “awareness” mode is automatically turned off when the last email has been sent.

Here is an example of data controller with two SQL business rules that will generate an email with report attachments when a product category has been updated.

A data controller with two SQL business rules that will generate email notifcations in Touch UI application created with Code On Time.

The first SQL business rule is very simple

Property Value
Type SQL
Command Name Update
Phase After
Script
set @BusinessRules_EnableEmailMessages = 1

The script of the this rule assigns value True to the BusinessRules.EnableEmailMessages property of Boolean type and does nothing else. The implementation of the script may do any other type of processing if needed.

The mode of email message awareness is activated now!

The second SQL business rule will produce a singe data row. The script has a “debug” section that declares parameter values used for testing. Application framework will remove this section at runtime  before asking the database server to execute the script. The highlighted fragments are the output column names.

Property Value
Type SQL
Command Name Update
Phase After
Script
-- debug
declare @CategoryID int
declare @CategoryName nvarchar(5)
select @CategoryName = 'Confections', @CategoryID = 1
-- end debug

declare @CrLf as varchar(2)
select @CrLf = char(13)+ char(10)

select 
    -- from 
    'YOUR_EMAIL_ADDRESS@gmail.com' "From",
    -- to
    'RECIPIENT@nothwind.com' "To",
    -- subject
    'Category "' + @CategoryName + '" has changed' "Subject",
    -- body
    'Dear Admin' + @CrLf + @CrLf +
    'This product category has been changed.' + @CrLf +
    'See attachment for category product details.' + @CrLf + @CrLf +
    'System Monitor' + @CrLf  +
    -- attachment 1
    '<attachment type="report">' + 
    '<name>' + @CategoryName + '</name>' +
    '<controller>Categories</controller>' + 
    '<view>editForm1</view>' +
    '<filter>' + 
        '<item>' +
              '<field>CategoryID</field>' +
              '<operator>=</operator>' + 
              '<value>' + cast(@CategoryID as varchar) + '</value>' +
        '</item>' +
    '</filter>' +
    '</attachment>' +    
    -- attachment 2
    '<attachment type="report">' + 
    '<name>Products in ' + @CategoryName + '</name>' +
    '<controller>Products</controller>' + 
    '<sortExpression>UnitPrice desc</sortExpression>' +
    '<filter>' + 
        '<item>' +
              '<field>CategoryID</field>' +
              '<operator>=</operator>' + 
              '<value type="Int32">' + 
cast(@CategoryID as varchar) +
'</value>' + '</item>' + '</filter>' + '</attachment>' "Body"

Note that STMP parameters, such as Port and Password are omitted from the script. Application framework will use default SMTP settings from the application configuration file. If any of these parameters are needed to be in the message definition, then make sure that the values are included as the corresponding column names (for example, Host, UserName, etc.)

This particular implementation uses @CrLf parameter to inject end-of-line characters in the message. The entire message body is a single concatenated string of text. A real-world implementation may compose the text by iterating through cursors and executing multiple select statements.

If an HTML output is desired then the corresponding tags should be included in the “Body”.

Developers can return any number of “messages” in the output when needed. This may be accomplished by creating a temporary database table and populating it with the messages. The contents of the temporary table are selected when the job is done. Another alternative is to use UNION of several SELECT statements to send a fixed number of messages at once.

This is a sample email notification produced by SQL business rules from the example above.

An email notification with two report attachments produced by Touch UI app created with Code On Time.

Thursday, July 31, 2014PrintSubscribe
Introduction to Data Controllers in Code On Time

Controllers are the backbone of any Code On Time web app. The Code On Time application framework uses these XML files as a definition for how the application will work and be interacted with by the user.

Structure of a data controller.

Each controller may contain an automatically created command – essentially a list of developer-friendly field definitions that will be used by the application framework to create on-the-fly SQL commands for Create, Read, Update, and Delete operations. A list of fields will be added that match up to the fields in the table. Several default views will be created so that the user can perform CRUD operations, each view containing data fields that bind a field to a view. In addition, a standard set of actions will be added to provide a fully functional action state machine at run-time – users can select, edit, print reports, create RSS feeds, and more. These actions are placed into action groups that determine where the action is displayed in the user interface.

Controllers can be instantiated on a page using data views placed on these pages (not displayed in the above diagram).

There are multiple ways of creating controllers in order to allow users access to data.

1. Automatic Creation From Database

When a Database Connection string is specified during the creation of a web app, the app generator will create a data model of the tables and views specified by the developer. Then, controllers will be composed from the data model with various optimizations that result in a fully functional application out of the box. Provided that the table has a primary key defined in the database, users will be able to insert, update, and delete records without any work on the developer’s part. The developer can then proceed to modify the design of the controller using the Project Designer to their heart’s content.

This is the easiest method to define controllers, as it is all done automatically by the generator. Note that it requires pre-defined tables and views in the database.

2. Generating a Controller from SQL Query

The Project Designer also allows the generation of controllers from a developer-defined SQL query. The script can be of any complexity – feel free to use any combination of UNIONs, JOINs, GROUP BYs, sub-queries, or any other SQL functions to sculpt the result into the correct shape. The picture below shows an example of such a script.

Defining a data controller from an SQL query.

The application generator will take the script result and compose a data model. Like with automatic creation, a controller will be composed with all the necessary elements, including a command.

Data controller elements created using the "Generate From SQL" option.

The controller will, by default, permit users to perform CRUD operations if a primary key was detected. The developer will have to mark the read-only fields, disable actions, and/or override the default commands with custom code or SQL.

3. Generating a Controller Using Business Rules

Another method to create a data controller is by defining a result set from an SQL query. This method can be used to display the results of stored procedures or other functions in the database. The “Define Data Controller” tool in the Project Designer allows specifying the SQL script and will compose the controller automatically. The controller will not have a command, and the Select action will be overridden with two SQL business rules. The first one will set EnableResultSet property to “true”. The application framework will then use the results of the second business rule to compose the result set. Three additional rules will prevent the user from triggering insert, update, and delete actions. An example can be seen below.

Defining a result set from an SQL query.

Once the controller is generated, a default set of views, actions, and business rules will be added.

The generated controller from defining a result set.

4. Generating The Controller From Web Service

If the controller will be used to display a result set from a web service or other programmable source of data, the developer can create the controller and define the fields using the Project Designer. Then, use the “Generate From Fields” option to create all views, data fields, actions, and several code business rules automatically, as shown below.

The views, actions, data fields, and business rules have been generated from the field definitions.

The first code business rule, with ID of “GetData”, will assign to the ResultSet property using an automatically generated method. The method’s default implementation will return an empty data table. It is up to the developer to implement retrieving data from the source (web service, static definition, etc).

The next three business rules will prevent the user from triggering any default Insert, Update, or Delete actions. The developer must implement the code for these actions to have any effect.

5. Creating the Controller Manually

The developer can always choose to create the controller manually in the Project Designer. While this may be more involved with creating the prerequisite elements, such as fields, views, data fields, and actions, the developer can create exactly what they deem necessary. In addition, the developer can define result sets from any source using C# or Visual Basic business rules, affording a greater complexity. It’s even possible to create a web-based file management system using a custom controller by using .NET’s file management classes. They are limited only by their ingenuity.

Thursday, July 24, 2014PrintSubscribe
Touch UI for Any Data, Anywhere (Stored Procedures, Web Services, etc.)

Code On Time release 8.0.7.0 introduces ability to generate custom data controllers directly from Project Designer. The source of data is up to you – the app generator will handle any data anywhere! Create amazing Touch and Desktop UI for data returned from stored procedures, web services, file system, etc.  The release also introduces a collection of important bug fixes and performance improvements. Continue reading for the full list.

Generating Controllers from Project Explorer

Create a new data controller, right-click the corresponding node in Project Explorer and choose Generate from SQL option to create a data controller based on a free-form SELECT statement , stored procedure, or any other SQL script .

'Generate from SQL' and 'Generate from Fields' options in Code On Time app generator.

“Command Text”  Controller

If the script is an arbitrary SELECT statement, then indicate that the script defines a command text. This option will configure a custom command for the data controller and ensure the maximum efficiency at runtime. You can also specify an optional “base” table name if you want the controller to support Update, Insert, and Delete.

Configuring a data controller based on arbitrary SELECT statement in Code On Time app generator.

Verify the script and click OK. Copy and paste the new controller on any page.

An app with Touch UI created with Code On Time.

“Business Rule” Controller

If you want to configure a data controller based on a stored procedure, then you will need to indicate that the script defines a business rule.

Configuring a data controller based on a stored procedure in Code On Time.

The controller will be enhanced with a collection of business rules. There will be no command.

Rule enableResultSet will instruct application framework to use the custom result set.

set @BusinessRules_EnableResultSet = 1
-- Enable caching of the result set. Duration is specified in seconds.
-- set @BusinessRules_ResultSetCacheDuration = 30 

Rule getData will produce the result set.

EXEC    [dbo].[Employee Sales by Country]
        @Beginning_Date = N'1/1/1980',
        @Ending_Date = N'1/1/2014'

Note that Update, Insert, and Delete are prevented by default.

set @BusinessRules_PreventDefault = 1
-- implement insert here

Implement your own business logic in the corresponding SQL or “Code” business rules. The output of the stored procedure will be stored in an instance of DataTable class. Developers can specify optional cache duration to improve performance of controllers based on “slow” stored procedures.

Business rules of a data controller based on a stored procedure displayed in Project Explorer of Code On Time app generator for desktop and mobile devices.

Drop the controller on a page to see it in action.

A data controller based on a stored procedure displayed in Touch UI application created with Code On Time.

“Thin Air” Controller

If you data is not coming from the database, then use another approach. Define a collection of fields for the new data controller. Right-click the data controller and choose Generate from Fields option. This will create a collection of “Code” business rules that produce an empty DataTable class instance with the columns matching the data controller fields.

A custom data controller produces data from 'thin' air in an app created with Code On Time.

Implement the code to populate the DataTable instance in the file that contains GetData business rule.

Imports MyCompany.Data
Imports System
Imports System.Collections.Generic
Imports System.Data
Imports System.Linq
Imports System.Text.RegularExpressions
Imports System.Web
Imports System.Web.Security

Namespace MyCompany.Rules

    Partial Public Class CustomDataSource3BusinessRules
        Inherits MyCompany.Data.BusinessRules

        ''' <summary>
        ''' This method will execute in any view before an action
        ''' with a command name that matches "Select".
        ''' </summary>
        <Rule("GetData")> _
        Public Sub GetDataImplementation()
            ResultSet = CreateCustomDataSource3DataTable()
        End Sub

        Private Function CreateCustomDataSource3DataTable() As DataTable
            Dim dt As DataTable = New DataTable()
            dt.Columns.Add("Title", GetType([String]))
            dt.Columns.Add("Published", GetType(DateTime))
            dt.Columns.Add("Reviewed", GetType(DateTime))
            '
            ' Populate rows of table "dt" with data from any 
' source (web service, file system, database, etc.) '
Dim r As DataRow = dt.NewRow() r("Title") = "Building modern applications with Code On Time" r("Published") = New DateTime(2014, 12, 15) dt.Rows.Add(r) Return dt End Function End Class End Namespace

Note that Update, Insert, and Delete commands are prevented by default. You can implement your own routines when needed. Also make sure that you have specified the primary key fields to allow selection of data .

Here is the data controller in a live application.

A data from 'thin' air displayed in an app with Touch UI created with Code On Time app generator.

This feature is available in all product editions. Detailed tutorials with step-by-step instructions will be published later this week.

Bug Fixes and Enhancements

The release includes an important fix for Unlimited edition users. Generated applications were failing previously if the browser was not supplying Accept Encoding header in HTTP requests, which resulted in a non-function page displayed to the end users in both Desktop and Touch UI. The web server was reporting HTTP error 400 (Bad request).

Application framework will also not execute custom business rules twice. The bug was introduced in the previous release.

Business rules are not executed for the selected and unchecked row when multiple selection is enabled in Desktop UI.

This is the list of other enhancements and bug fixes included in the release:

  • Non-IE desktop browsers will not report “Invalid date” message in Touch UI.
  • Touch UI updates all visible summary views in Touch UI when a page is resized.
  • Filter information and "Clear" option are displayed correctly in master and detail context menus in Touch UI.
  • Summary views in Touch UI do not wrap "See All" option on the next line.
  • Touch UI displays "Showing N items." message in the view description.
  • Item styles RadioButtonList, ListBox and CheckBoxList are now supported in Touch UI. The latter enables many-to-many fields.
  • Method $app.mobile.activeLink will not strip "focus" from the active tab on touch-enabled devices.
  • Touch UI now uses action header text, command name, and command argument to eliminate duplicate actions from the context menu. Previous implementation has relied on command name and argument only, which have resulted in “lost” context menu options.
  • Fixed the bug in Quick Find that was causing incorrect search results when fields "shorter" than the search sample are present in a grid/list view.
  • Navigating to a "hashed" url of a protected page will not cause a duplicate history event in webkit browsers.
  • Page title is displayed inline when sidebar is visible to allow more space for toolbar buttons.
  • Taphold on field value in a grid column will display a popup with a complete text of the field value if the value is partially hidden.
  • Touch UI allows static text selection with a mouse in desktop browsers.
  • Fixed page height decrease caused by a refresh of a summary view in Touch UI.
  • Removed "keyup" and "keydown" events causing appscrolling  event in wrappers in Touch UI applications.
  • Taphold can be done with Ctrl+Click when using a mouse in Touch UI applications. The other option is to press the mouse button down and holding it at least 750 milliseconds before release.
  • Fixed ResetSkipCount method to ensure that a correct page is loaded from Result Set under all conditions.
  • User and Role manager have been improved for a consistent behavior in Desktop and Touch UI apps.
  • Sync of selected key value is performed by application framework if the number of submitted key values matches the number of primary key fields.
  • Focus on an input field in Touch UI will also select the field value.
  • Blob key field is converted to a string when a check for "null" BLOB field is performed in Touch UI.
  • Removed icons-png folder from the ~/touch/images folder of generated apps. The complete set of SVG icons available in Touch UI are now listed in ~/touch/icons.html file includes in every project.
  • Fixed Export exception when server rules are null.
  • Ensured EnableMinifiedCss is generated for all users.

The next release will be out in early August of 2014. We expect to include further enhancements to the Touch UI and a new server-side Reporting API that will produce binary reports on the server. The feature will also be extended to Email Business Rules to enable reports as attachments.