IxSay
The Interacx Development Journal
Documentation (2)
Gotchas (2)
Internal Workings (6)
Misc (4)
New Features (3)
News (5)
Table Level Calculated Fields
8/6/2007 9:14:17 AM

To support the union join type, I've added table-level calculated fields. For example, these fields are necessary to create stubs for fields in table A that do not map to a field in table B. The table level calculated field only supports SQL expressions. For example, you may create a calculated field (as a placeholder) that is an empty string or the numeric value zero.

Unions
8/6/2007 9:12:19 AM

Union joins are now supported as a join type in the virtual view. The main limitation at this point is that all tables must be union'd in the view--there is no support for using inner, outer, left, or right joins along with another table that is union'd.

Also not implemented, but certainly doable, is adding a tag on the row to indicate which table the row originates from, so that updates and deletes can manipulate the correct table automatically.

Interacx manages the field ordering in each select statement by using the first table in the union to specify the field order. This then drives the field order in subsequent select statements.

View level calculated fields with SQL expressions are automatically concatenated to each table select. Views of union'd tables do not currently support client-side .NET expression evaluation, mainly because I haven't tested this.

New SQL Data Types
8/5/2007 4:52:00 PM

The following SQL data types have been added to the data types supported by the Schema Designer:

  • varchar
  • text
  • tinyint
  • smallint
  • decimal
  • xml

Interacx Presentation
7/2/2007 12:37:33 PM

I did a short presentation of Interacx at the Albany BarCamp a couple weeks ago. It was very well received and I saw a lot of nodding heads (no, not nodding because they were falling asleep!) to my design rationale for the Interacx architecture.

If you've never been to a BarCamp, I highly recommend them. It was a fantastic experience crossing a wide variety of technologies.

Containers and Notifiers
Why doesn't my notifier work?
7/2/2007 12:33:49 PM

I long time ago, when I wrote the notifier service, it occurred to me that the notification doesn't need to be sent back to the same client that generated the transaction that triggered a notifier. However, there are obviously cases when the same client might have two different views--change one view and you want the other view to reflect that change.

When I use the Interacx Form Designer to create a UI form, I typically create a container whose name is associated with that view, and usually I'm not loading the same view as in another form. However, I tend to use the same container when writing client plugins. So naturally, I came across a problem where changes to view A were not creating notifications to the view B on the same client. Why? Because I was using the same container, and the session-container does not get a notification.

The solution is simple--create a different container. But it's not an obvious solution, and I will have to go back and change the server code so that it looks at the session-container-view tupple to determine whether the client should receive a notification.

Why I Wrote Interacx
General Background
6/21/2007 2:17:19 PM

Why Did I Write Interacx?

I wanted a tool that allowed me to write client-server applications as quickly and easily as possible.   I’ve experienced the drudgery of writing SQL for every CRUD operation, the frustration of having to instrument every transaction because they were scattered all throughout the code calling into the DB API directly, the pain of making minor business rule and UI tweaks, the fear of adding new features because the data access layers, business rules, and UI’s were all entangled. 

After doing it wrong once, ok maybe more than once (many years ago), then doing it better with a generalized automation API (but still 2 tier, still hand coding SQL statements), I felt that I finally acquired enough experience to do it right.

What Is The Right Way?

The right way for me is:

·         In General:

o   The client should be generic—any application specific stuff is done as plug-ins

o   The server should be generic—any application specific stuff is done as plug-ins

o   Centralized transaction points for traceability

o   Small client API easily unit tested

o   Small middleware features easily unit tested

o   Server architecture implemented as “services” with interfaces

·         The communication layer:

o   Should be as lightweight as possible (no heavy .NET serialization).

o   Should be secure—asymmetric keys

·         The middleware should:

o   Serve the client forms and reports—makes it easy to update all clients without stopping the client

o   Use virtualized views (not SQL views) so that it can manage view-based CRUD operations

o   Provide a mechanism to write server-side business rules triggered on transactions--  There are several advantages to doing this in the middleware rather than in the DB (flexibility, easily overridden [merging], unlimited capability [launch apps, etc], version control the source [DB’s are just getting to that point], traceable execution…)

o   Generate SQL automatically from the schema

o   Automate table dependencies with regards to CRUD operations, using the schema to determine insert order, cascading deletes, etc.

o   Implement extended features, such as using a delete flag to mark a record as deleted rather than deleting the row

o   Robust—catch exceptions and pass them to the client

o   Instrumented—log communications, transactions, exceptions, business rule triggers

·         The client:

o   Derive from platform API controls—allows me to add necessary automation to the UI controls

o   Client API platform agnostic (no WinForm dependencies).  Interface used to implement client platform specific functionality—this allows me to implement console, WinForm, and Web-based applications easily

o   No data access layer in the client—the client communicates to the middleware for all DB operations

o   No ORM—the client automates databinding without the use of ORM

o   Robust—catch exceptions and execute predefined workflow for handling and reporting errors

o   Instrumented—log workflow events, communications, exceptions

·         Forms:

o   Client forms should be in XML—makes it platform neutral (including implementing as a web app)

·         Reports:

o   Report definitions persisted in XML on the server

o   Can be served to the client to run locally

o   Can be run at the server and the resulting output sent to the client (for web apps)

·         Scripted Workflows (client side):

o   Expressed in XML

o   Functionality can be changed at the server and propagated to clients automatically

o   Decouples layers—workflow implements a mediator between disparate objects

o   Exposes common operations—100% of typical operations can be handled by workflow automation

o   Provide mechanism for plug-ins to expose methods callable by the script

·         Scripted State Management:

o   On the list to implement

o   Manage UI state

o   Manage application state

·         ORM:

o   Support generation of classes from view specification—used by server and client-side business rules if necessary.

·         Start with tools—so we’re not editing XML:

o   Schema designer

o   Form designer (includes workflow and state definition)

o   Report designer

·         Security:

o   Role based menu permissions

o   Role based UI control state (visible, enabled)

o   Role based data access (not implemented)

·         Compromises:

o   All tables have a single PK

o   PK is GUID

o   XML merge not yet supported

o   Role-based security is currently weak, implementation may need to be revisted

How Do We Start?

We start from two ends more or less simultaneously—the schema and the client UI.

The Schema

The schema actually isn’t necessary.  Interacx can be used a form server without any associated DB.  A DB is usually associated with a client-server application.  The schema consists of two parts—table definitions and view definitions.

Table Definitions

The tables define the optimal way for the DB to manage the user data requirements.

View Definitions

The views define the optimal way to combine the tables into different associations that are suitable for visualization at the client and/or manipulating data via business rules.  All server operations against the database are done with views.  Tables are never directly accessed.  The client exposes only view-based operations.  This leverages .NET’s DataView capabilities, which are quite useful.

Schema Management

Interacx stores the schema on the server as an XML file.  The server uses the schame for SQL generation.  The client requests the schema and uses it for validation and default value automation.  The schema is DB agnostic.

The Client UI

Obviously, some applications don’t have a UI, or at minimum, are a client console app.  In this case, there are no forms to define, but the client application might still want to take advantage of the scripted workflow as a mediator pattern for managing plug-ins.

Typically, the client has a UI consisting of some number of forms.  The goal of the Interacx client is to automate, as fully as possible, the visualization of that data.  This includes data binding, row cursor management, validation, persistence and rollbacks.  By automating these tasks, they alleviate the programmer from the drudgery of managing these tasks in code and provide a centralized, provably correct (unit tested) automation architecture. 

Form Layout

The UI consists of a form with controls, a menubar, a statusbar, a workflow and a state machine.  Any one of these are of course optional.

Controls

Controls are derived from the .NET controls, so that I can add the code necessary for the automation engine.  In many cases, this amounts to basically nothing at all, in other cases it can be a fair amount of code.

One of the decisions I made was to go with a stand-alone designer that is not based on the Visual Studio designer.  I did for two reasons: I’d like to ability to port the designer to other platforms, and I didn’t want to be tied to the vagaries of Microsoft’s designer and frequent changes.  Yes, the Visual Studio designer in VS 2005 is really good looking, but the designer is such an integral aspect of Interacx, tying it to .NET’s designer support seemed like the wrong direction.  Then again, there’s no reason that a .NET-based designer couldn’t be used.  Incidentally, I use the same architecture (which I’ve written an article about) for the schema, form, and report designers.

I also wanted to limit the number of properties exposed in the designer.  For one thing, with the automation framework, one has to be careful as to what properties are exposed—some may break the automation (such as allowing the user to bind a control to a data source—a definite wrong thing to do) and others may not be supported by the automation framework (or should be supported intelligently rather than the rather coarse way properties are handled in .NET).  Exposing specific properties also means that it’s easier to port the control to another platform—not every one of 500 properties needs to be implemented!

Workflows

Workflows are one of the key aspects of Interacx.  The workflow service is like a plug-in manager.  The client workflow service provides a variety of automation methods for loading and saving data, binding that data to controls, and managing the transaction of those controls.  In addition, client-side plug-ins can expose methods that become accessible to the workflow service.  A large number of forms can be managed entirely with workflows, including undo/redo, sandboxing, and master-detail management.

Workflows are triggered by UI events from controls like buttons.  The programmer does not write code for wiring up a UI event to some processing algorithm.  Instead, the event is wired up to a workflow.  Among other things, this creates the possibility of running the application in a web form, where a UI event posts a callback to the web server which executes the workflow.  Or, in a more exotic scenario, the workflow functions are implemented in JavaScript (perhaps even dynamically) and “Ajaxed”.

State Machine

Not implemented (a separate state service currently exists).  The purpose of the state machine is two-fold.  To manage the UI state, mainly control visibility and edit state, and to manage application-specific state with which a plug-in would interact.

Decision Graph

Not implemented (a separate decision graph service currently exists).  The purpose of the decision graph is to externalize complex decision rules that determine the application state, state transition, or workflow event.

Transaction Management

The heart of Interacx is a transaction manager that logs all DataTable transactions.  I spent a lot of time researching and building this component so that it can accurately log field and row changes.  A subset of the transaction manager supports undo/redo capability, a very nice feature that allows the client application to feel like a “real” application rather than that feeling you usually get, that you’re closely tied to a database.

Sandboxing Management

Sandboxing is another feature that I spent a lot of time on.  The idea is to allow the UI to look like a typical application with “OK” and “Cancel” buttons rather than a DB application where a field change is immediately committed to the DB, especially when changing the row cursor.  Sandboxing lets the application accumulate all the transactions and post them when the user clicks on “OK”, and of course they can be completely discarded when the user clicks on “Cancel”.  Sandboxing is not something that is required when creating a Form—it’s up to the application designer and the user requirements as to whether the form (or a section of the form) should be sandboxed.

Conclusion

Interacx is more than a form server and more than an SQL generator.  It encorporates a variety of design patterns to provide the programmer with considerable automation in developing a sophisticated client-server application—plugins, workflows, UI data management, transaction management, communication, and security.

Marc

Cascading Deletes
and the Deleted flag
5/23/2007 11:27:28 AM

A while ago I wrote about an issue with cascading deletes with regards to tables that use a Deleted flag to indicate that a record is deleted.

The problem has now been corrected (it was at the low priority, obviously). In addition to the expected behavior (the deleted flag gets set) the server now also nulls the appropriate field in the table that is referencing the row in the foreign table that is being deleted.

Once a table with a flag for deleting rows is encountered, the server stops the cascade process, which ensures that dependent rows downstream are not deleted. After all, the point of the deleted flag option is to preserve the row data.

Marc

The Form Designer
Why does Interacx use a standalone form designer?
3/16/2007 9:23:26 AM

I admit I've taken a bit of a radical approach to how controls are exposed in the designer. All "Interacx" controls (even the standard .NET ones) are derived from the desired control. The designer itself specifies (in XML) which properties are exposed.

There's two reasons for this--the control needs to know a little bit about the client framework, for example to tie events into the workflow mechanism, and in the case of list/table controls, to automate some of the binding of data with the control. Secondly, I feel (more radical thoughts here) that the typical control exposes far too many properties. So I use an XML configuration file to decide what properties really need to be exposed. Lots of pros and cons to that approach.

So...Any control that isn't supported by the Interacx client will need a subclass that defines the IXPressControl interface and possibly the IXPressDataSourceControl interface as well.

Why did I write my own designer? Because I didn't want to be dependent on whatever flavor of VS came out. I wanted something potentially capable of being cross platform as well. I wanted something that could migrate to working with web page layout issues like flow control. I wanted something that ultimately worked in an integrated way with vector graphics designs. So, there's lots of planning for the future that I felt was not going to be possible within the VS architecture and being at the mercy of Microsoft.

Which means I made my own life a lot more difficult.

That said, the idea also is that there's a high level of automation provided by Interacx, and so a lot of properties actually shouldn't be exposed, or should be handled more intelligently. For example, setting the visual style is probably something that ought to be defined by something coming from the server, possibly even managed per user, rather than being wired into a client configuration file.

One more thing--there's nothing requiring you to use the Interacx form designer. If you can serialize to XML whatever VS generates, serve it to the client, and reconstruct the UI, then that's cool too. My experience with these third party controls though is that they are NOT XML serialize-friendly. Another reason for my subclass / standalone designer approach.

Marc
Cascading Deletes and the Deleted Field
Or, an investigation into nullable FK's
3/15/2007 11:49:48 AM

I set up a table to use a field to designate that deleted records should be marked deleted as opposed to actually physically deleted from the data store:

The issue with this table is the last field, "PhysicalKioskId". This is a nullable FK. When a physical kiosk record is deleted, the server realizes that the delete has to cascade. This results in two problems. First, all the records dependent on the kiosk are deleted, but then the kiosk record itself, because it has a DeleteFlagField, doesn't delete, it merely sets this flag. Then, when the physical kiosk tries to delete, Kiosk.PhysicalKioskId still has the FK and the final delete fails. Fortunately, the entire transaction rolls back.

What really needs to happen is the server to recognize that the delete flag field should be used and not cascade further past the Kiosk table. It also needs to realize that the Kiosk.PhysicalKioskId should be set to DBNull.

Which also points out to the schema designer that, when using a delete flag field, certain FK's need to be nullable.

I'll post another blog entry when I've resolved this issue.

Marc

A New Look
New Webpage Design, New Blog
3/14/2007 9:21:11 PM

The website for Interacx has finally gotten a cleaner look, and the blog engine has been changed.

Marc

RSS
August 2007 (3)
July 2007 (2)
June 2007 (1)
May 2007 (1)
March 2007 (15)

(c) 2007 Interacx
MBlog (c) 2007 Marc Clifton