2007-02-19

Delphi editor shortcut

I've had a conversation with a few people recently and it turns out they weren't aware of this Delphi editor shortcut. Seeing as I am old enough to have written COBOL apps using WordStar I have known this one for some time :-)

CTRL+T = This will delete the token / whitespace to the right of the caret. I use it all of the time!

2007-02-16

ECO JumpStart

I've been up quite late working out what I want to cover in the "ECO jump start" document. The trick is to start at a level where the user knows absolutely nothing, and end up where they know enough to decide whether or not they wish to spend some time learning how to use ECO or not.

I think I should start off explaining why multi-tiered app development is a good idea; then I think I should go on to creating a package in a DLL; then onto creating a non-persistent WinForm app using that package; then make it persistent; and so on. My problem is that ECO just does so much!

I'll paste what I have so far at the bottom of this blog entry to get any feedback. As the list progresses the subjects become more advanced and I am worried that the jump start might actually frighten people off by making them feel overwhelmed. Maybe I should just take it so far and then leave the more advanced items out? Maybe I should just include a section at the end of the document explaining what advanced features are available without demonstrating how to use them? Then maybe do an "Advanced ECO" document in which I follow on where I left off and demonstrate the more advanced stuff.

At the moment I am undecided, what do you think? Remember, this document is really intended to server two purposes; it should be there to help new users to understand ECO, and also to act as a promotional ("marketing" if you like) document to boast how good ECO is without scaring people away.

And now the table of contents:


Overview
Why create separate layers (GUI / Business / Data access)
An overview of how ECO uses UML as the design tool to sepcify the business layer
Explain that ECO can persist those business objects in a number of ways, the DB being switched in a matter of seconds


Creating a business classes package
Create project
Add references
Configure package settings
Add 2 classes with n--m association
Add properties
Add association
Generate code

Creating a non-persistent WinForm app
Create ECO WinForm project
Add reference
Select packages

Adding some simple GUI
Delete all but rhRoot
(Design support)
Set EcoSpace type
Add DataGrid
Set EcoSpaceType
Add ExpressionHandle (allInstances)
Bind the datagrid to the ExpressionHandle

Adding new objects
Add EcoListActions
Set RootHandle
Add button
Set the ListAction to Add

Drag and drop
Add another ExpressionHandle
Add another DataGrid
Add another "Add" button
Add CurrencyManagerHandle, set parent = DataGrid1
Add ExpressionHandle, expression = "self.AssociationToOtherClass"
Add a DataGrid
Add DragDrop extender
DataGrid2 = DragSource
DataGrid3 = DropTarget
Run + create + drag/drop

Making the objects persistent
Add XML persistence to EcoSpace
Add EcoGlobalActions to form
Connect to RootHandle
Add button
Set GlobalAction to UpdateDatabase
Run, create, save, close, run

Creating a database
Remove the XmlPersistence
Add DB persistence + set configuration
Add connection
Generate DB
Run, create data, save

Evolving a database
Add new properties
Rename a property + set FormerName
Add new super class + move property up
Evolve DB
Run, show same data

Quick prototyping the model
Set AutoForm = True on grids
Run app, show auto forms
Add button
Set GlobalAction = debugger
Run app, show debugger, show access to auto forms

State machines
A simple state machine with triggers
Triggers with paramters
Transitions with guards
Multiple transitions out of a single state with guards (explain how only 1 must be true)
Multiple transitions out of a single state with the same trigger
Nested regions
Concurrent regions
Final state

Multi user
Unloading the cache to see changes by other users
Turning on optimistic locking
Getting conflict information
ChangeActionKind
Locking regions

Remote persistence
Creating the remote persistence server
Registering as a remotable server
Registering as a HTTP remotable server available via IIS
Switching the WinForm to RemotePersistenceClient

Multi user synchronization server
What it is, how it works
Adding it to the remote persistence server
Requesting changes from the WinForm client
Run two apps, show the propagation of changes between them

ECO and ASP .NET
Create ECO web application
Reference the same model
Explain why we have a PersistenceMapperProvider component (only about caching the mapping information for now)
Show how to generate DB / evolve from PersistenceMapperProvider instead of the EcoSpace

ECO ASP .NET autoforms for protoyping in ASP .NET

Show the ECO WebForm
Recreate the same WinForm gui in a WebForm

ASP .NET performance
Show the pool size in Web.Config
Explain what happens when more people request pages than there are EcoSpaces in the pool
Explain the SessionStrategy
Explain the maximum lifetime setting in Web.Config

ASP .NET multi-user
Explain how EcoSpaces are kept in sync with each other via the PersistenceMapperProvider
Demonstrate how WebForm data is in sync
Demonstrate how the WinForm / WebForm apps do not stay in sync with each other
Migrate the ASP .NET app to use the persistence server
Demonstrate WinForm app reflecting changes to data made in a WebForm app

Overview of each of the ECO components

ECO in code
Switching between Object and IObject
Overview of some of the ECO services
UndoService, In-memory transactions + undo blocks
DirtyListService
PersistenceService
OCLPS Service
OCL service
OCL action language service


Advanced modeling techniques
HasUserCode = true
OCL derived attributes
Overriding OCL derived attributes in subclasses
Code derived attributes
Code reverse derived attributes
Derived associations
Transient properties
Transient classes
Transient associations
Association classes
Platform independant property types
AutoInc
Blob
Memo
Delayed fetch properties
Referencing other packages
Extending classes
Adding associations
Adding class constraints
Enforcing in a WinForm application
Enforcing the same constraints in a webform application
Disabling the auto-generated multiplicity constraints
Object versioning
Navigating historical data
Retrieving all historical versions of an object

Advanced database techniques
Reverse engineering a database
Cusomizing the mapping information to fit an existing database
Evolving the structure of an existing database
Using a single model to pull data from multiple databases (including mixed servers) and updating the data too

Disabling BlueTooth on a Pocket PC

We use wireless printing through a COM port over BlueTooth. Having BlueTooth on all of the time can contribute towards energy consumption and cause the battery life on the Pocket PC to deplete faster. Now I disable BT when the application starts, and then re-enable it to print and disable it immediately afters. This adds about 1 second to each print job but it should save the battery power.


[DllImport("BthUtil.dll")]
private static extern int BthGetMode(out BlueToothRadioMode dwMode);

[DllImport("BthUtil.dll")]
private static extern int BthSetMode(BlueToothRadioMode dwMode);

public static BlueToothRadioMode BlueToothRadioMode
{
get
{
BlueToothRadioMode result;
BthGetMode(out result);
return result;
}
set
{
if (value != BlueToothRadioMode)
BthSetMode(value);
}
}

2007-02-14

Keeping a Pocket PC awake

My compact framework application imports XML into a local database. As there is so much data to import this can take up to an hour. During development there were no problems with this, but of course during development the Pocket PC is docked in its cradle which provides it with power.

When a Pocket PC is removed from its cradle it manages power differently, just like an unplugged laptop. So every five minutes the Pocket PC would hibernate and the user would have to turn it back on in order for the import to continue. During an hour the user would have to do this approximately twelve times. How annoying, and dangerous too if the employee is driving to their first job.

Anyway, I found the following very useful code on the web and thought I'd point it out as it was so useful!


public class Device
{
#region Device sleep support
[DllImport("CoreDll.dll")]
public static extern void SystemIdleTimerReset();

private static int DisableSleepCallsCount = 0;
private static System.Threading.Timer PreventSleepTimer = null;
#endregion

public static void EnableDeviceSleep()
{
DisableSleepCallsCount--;
if (DisableSleepCallsCount == 0)
{
if (PreventSleepTimer != null)
{
PreventSleepTimer.Dispose();
PreventSleepTimer = null;
}
}
}

public static void DisableDeviceSleep()
{
DisableSleepCallsCount++;
if (DisableSleepCallsCount == 1)
{
TimerCallback keepAlive = new System.Threading.TimerCallback(
delegate(object applicationData)
{
try
{
SystemIdleTimerReset();
}
catch (Exception)
{
}
}
);
PreventSleepTimer = new System.Threading.Timer(keepAlive, null, 0, 30 * 1000);
}
}
}


Now I can do this


Device.DisableDeviceSleep();
try
{
//Do stuff
}
finally
{
Device.EnableDeviceSleep();
}

2007-02-12

Dotting the I's and crossing the T's

Ever played "Spot the difference"? I'm sure you have :-)

I'm just looking through an application I have inherited from a Turkish company it was outsourced to. I was just browsing through a 5MB SQL script to generate the DB + stored procs when I saw this....

@MATERIAL_CODE=REPLACE(@REPLACE_MATERIAL_CODE,'Imprinter','Imprınter')

Does it do anything? Sure it does, but can you see what it is? There are two clues in this post but I wont tell you where!

2007-02-07

ECO book at last!

Hi all

I have finally reached a point where I can dedicate a few hours each today to "something new" and have decided that the ECO book I have always wanted to write would be great fun. My first idea is to create 2 or 3 separate items:

Title: ECO jump start
This would be in paper / PDF format and would contain a set of exercises for a new user to follow in order to get started with ECO as quickly as possible. It would basically cover creating a simple model, prototyping using auto-forms, using the different handles, databinding, parent-child grids, creating/evolving the DB, OCL / code derived / reverse derived attributes, and stuff like that.

Title: ECO API
This would be an electronic format which would basically be a "Press F1" reference.

Title: ECO book
This would either be a paper/pdf format or, if possible, part of the ECO API document. It would be a technical overview of the framework + its services and abilities. I imagine it might be similar to my ECO Services chapter, except I'd probably include a set of "How to" items at the end of each chapter.


The plan here is that we get

1: An easy way for people to assess exactly what ECO does, and to quickly start creating simple "test" applications.
2: A complete reference for information on specific items where you would normally find yourself hitting F1.
3: A conceptual overview of the whole thing, explaining how it all works together and how to achieve certain goals.


This is what I have in mind at the moment, but it could all change based on the feedback I get :-) The above is basically the order I learned in when I learned Bold and then later moved over to ECO, it goes from simple through to in-depth. What I want to know is

A: Do you think I should go for 3 separate items or try to combine the last 2?
B: Is there anything I have missed?
C: What information would you like to see?

As a closing note I will paste in a table of contents I wrote 729 days ago when I first decided this would be a good idea if only I had the spare time :-) It's not necessarily what I still have in mind, but it might get some brain cells bubbling in your heads to get us all started off. If there are any topics you guys mention that I have missed I will add them to my list. Due to its age (1 day short of 2 years old) it is based on ECO II, so there are lots of nice new ECO III items I can put in such as creating your own services, state machines etc.


An overview of ECO
What is an ECOSpace
Modeling an application
Attributes, Methods, and Relationships
OCL Derived attributes
Code derived attributes
Reverse derived attributes
Inheritance Vs Composition
Packages
Creating a simple ECO WinForms app
Creating a simple ECO ASP.net app
Creating a simple ECO Webservices app
Borland.ECO namespaces
Handles
ObjectRepresentation
Persistence
Services
Subscription
UmlRt
WinForm
Persistence
Changing persistence
Evolution
Custom persistence mapping - AutoInc etc
Reverse engineering an existing database
OCL



Also need to include multi-user support, optimistic locking, change propagation, reconciliation, object locking regions, writing your own services + OCL extensions.



Thanks for your feedback!


Pete

2007-02-01

ECO extensions 2.1 released

I have just released a minor update to ECO extensions. It contains a fix for a bug that would prevent the DirtyObjectCatcher from catching modified objects for MDI child forms.

string.GetHashCode

I recently developed a simple support application that allows users on a PC to provide a one-off security number to a Pocket PC user and when entered the PPC will perform a specific support function.

I used the same class to generate these security codes in both the desktop and compact framework applications, tested it quite thoroughly and it all seemed to work fine. However once deployed it became evident that the codes provided by our support department were being rejected by the PPC as invalid. So what went wrong?

Seeing as the same class was used for both applications I thought it would be okay to test the encoding/decoding of command numbers on only a single platform, and this was my mistake! The routines use string.GetHashCode() to add a checksum to the end of the security codes just to prevent the user from performing actions without authorisation. For reasons I cannot imagine the implementation of string.GetHashCode() is different in the compact framework from the one in the full .NET framework. It was due to the result of this method being different on the two platforms that the codes were being rejected.

So, I have disassembled the compact framework version and used that in my desktop application instead, and now it works just fine. Here is the code....

public int MyHashCode(string value)
{
int charIndex = 0;
int num1;
int num2 = 0x1505;
int num3 = num2;
char currentChar;
while (charIndex < value.Length)
{
currentChar = value[charIndex];
num1 = (int)currentChar;
num2 = ((num2 << 5) + num2) ^ num1;

if (charIndex == value.Length - 1)
break;

num1 = value[charIndex + 1];
if (num1 == 0)
{
break;
}
num3 = ((num3 << 5) + num3) ^ num1;
charIndex += 2;
}
return (num2 + (num3 * 0x5d588b65));
}