Chapter 3 - VAR programming

A tale of 2 servers: Socket or COM.
Programming  tools: Scripting, VB6 or VB5, Other toolkits.
Scripting
VB/ActiveX Project organisation and Language notes.
How to emulate some common MV and DATABASIC practices.


A tale of 2 servers: Socket or COM.

The core of PixieEngine is an "ActiveX/COM" server. To service "classic" terminal-style operation, a "Socket" add-on is provided.

Our recommended setup is "thick client" where your VAR-App along with the PixieEngine Package is installed on every client machine and can therefore use the supplied PxEngLink.exe front end or your custom front end, eg customised Excel, connecting via ActiveX.  We have found maintenance of such networks to be quite OK.  It is possible to script installation of new VAR-apps with such tricks and treats as .bat files triggered by desktop icons labelled "Upgrade".  There is also a  maintenance advantage of not needing to get all users off to do an upgrade or even minor adjustment to the central server. Printing is simplified, especially on a WAN.  And all the Windows components are on Windows clients so you can use a Linux MySQL server as the central datastore.   And you can use the supplied GUI-capable super-terminal-front-end so there is no additional charge for an emulator etc. 
BUT client machines do need to have sufficient grunt: CPU 166 MHZ or better with RAM of 32 MEG or better.  Some change of programming style is needed to get the MySQL datastore to pre-process data and send end-results across the network.  The simplest such change is to make more use of RREADV rather than RREAD so that entire items are not being pushed through the wire when not all attributes are required.  We also encourage the use of our RSOOPEN and SELECTARRAY methods for across-the-network use.

A "thin client" approach using the "Socket Server" has the advantage of staying close to the known environment of a classical MV setup.  It can service less powerful client hardware, and keeps all setup and maintenance issues concentrated on 1 or 2 servers.

Approaches can be mixed, we have set up an office where most users are "thick client", but some lower powered computers are serviced by a PixieEngine socket server.


Programming tools: Scripting, VB6 or VB5, other languages.


Scripting
Script support is new in PixieEngine 1.1, August 2000.
It requires only that the Windows scripting engine is available, which it will be if you have IE4 or above.  The latest VBSCRIPT and JSCRIPT package is available as a separate free download of about 0.5 MEG from
http://msdn.microsoft.com/scripting
PERL should work in theory but is untested at the time of writing.
Scripts take the form of Windows text files.  See subfolder "script1" for examples. The technology and usage is very like the way .asp scripting is done in webservers.  2 main differences: 
(1) We have provided the XRun function which allows you to call Subs and Functions in other scripts, thus getting scripts to better emulate DATABASIC Program behaviour.
(2) The DATABASIC-like functions eg DCOUNT, FIELD, MATCHES, RREAD, WWRITE are built in to our scripting environment and so there is no need to use a dot operator.
eg .asp webserver vbscripting:  
n = Pixie.DCount(sCust, "*") 
..becomes in PixieEngine vbscripting a more familiar 
n = DCount(sCust, "*")


VB/ActiveX

Start a project by copying our ready-made project example folder. It already contains object references, the class "BP" and the module "basPxLibrary".  Under project "properties", change the project name from our example "px1" to your own project name.

Then begin the VB environment by double-clicking on "PxAppTemplate.vbp"

Check for the "project type" of "ActiveX dll".
Check that "Apartment Threaded" and "Unattended Execution" are checked and that they remain checked as you program and compile. You are doing server-side programming for multi-users and the "Visual" tricks and treats of "Visual Basic" are not welcome here. No message boxes or forms allowed. Stick with modules and maybe classes if you are feeling adventurous. Losing the "Unattended Execution" status is a sure sign that you have broken the server-side rules.

All "programs" in your App will be "Sub"s or "Functions". Any program that you will want to be runnable as a "verb" from TCL will be a Sub with no arguments, and it will need a simple interface routine in class BP.
Eg the "buddying" interface routine for "test2" :
Public Sub test2()
Call basExamples.test2
End Sub


Look through our supplied and commented example code to get the idea.

DATABASIC-like library functions come from 2 sources:
PxEngFns.dll adds its functions to the global language just by being included in the "Project References". PixieEngine.dll simulates the same effect via buddying routines in module "basLibrary". This means you can directly use "RRead", "Field", "Extract" etc in your code in a DATABASIC-like way. With VB5 or VB6, an "intellisense" feature causes a help guide to the function syntax to popup when you type in the function name plus a space or a "(". This popup is a nice confirmation that you have typed a valid library function. Eg

Note the use of "[…]" to show optional arguments.
Note a peculiarity of this intellisense, it always shows the "( …)" that go with the Call syntax, even when you are using the alternative Keyword+Spaces syntax.
Eg IInput s is equivalent to Call IInput(s)

You write your app in "bas" modules.

There are 2 approaches to variable types.

  1. Our examples follow the "Implicit Variant" approach which is also the VB default. "Implicit Variant" variables are created as you use them, and they assume "type"s eg "String" or "Integer" according to how they are used. This is very like DATABASIC and it is the easiest approach when adapting legacy DATABASIC code.
    NOTE a difference between DATABASIC and VB in this code:

    a = 5
    b = "5"
    If a = b Then Crt "Cross-type equality checks out OK"

    Most DATABASICs we have encountered will output the message. VB won't because it encounters a "type mismatch". In such situations you need this:

    If Val(a) = Val(b) Then Crt "Cross-type equality checks out OK"

    Val is "take as numeric".
  2. VB convention, almost religion amongst the VB community, is to start all modules, forms and classes with "Option Explicit". If you are sharing a VB system normally used by avid VB-ers and you prefer to work in a DATABASIC-like manner, then you will need to erase these, and even get into Menu: Tools --> Options to switch this behaviour off. With "Option Explicit", all variables must be declared, usually with a "Dim" statement. The benefit of this is that keeping track of your variable names can be easier. Almost always with "Option Explicit" goes the "type"-ing of variables with your "Dim" statements. Eg

    Dim s as String, i as Long, n as Long
    Dim sCust as String, sFieldPosn as String


    "Type"-ing variables makes apps run slightly faster.

    Strict type-ing is recommended for creating new apps when you are already familiar with working in this style with VB. Classical MV-focussed programmers, or anyone working with large quantities of code converted with "PixieMassage",  will prefer "Implicit Variants".


How to emulate some common MV and DATABASIC practices.

Select Lists and "READNEXT"

We may emulate these closely in later versions of PixieEngine if the demand justifies it, but in the meantime you need to use the closest VB equivalent, a "Recordset Object". In PixieEngine this is a read-only object which is remarkably similar to a select list, with some extended capabilities. Looking here at a direct comparison.

DATABASIC

OPEN "PROD" TO PROD.FILE
EXECUTE 'SELECT PROD WITH DESCR = "[CARD]"'
LOOP
  READNEXT ItemID ELSE EXIT
  READ S FROM PROD.FILE, ItemID
  CRT S
REPEAT

Visual Basic/PixieEngine


Dim rstProd As Recordset
RsOOpen "SELECT A0 FROM PROD WHERE A1 LIKE '%CARD%';", rstProd
Do
  ItemID = rstProd.Fields(0)
  RRead s, "testpxe1.prod", ItemID
  Crt s
  rstProd.MoveNext
  If rstProd.EOF Then Exit Do
Loop 

ONE-STEP method with the new ExecutePS function
This new method returns a 2-dimensional "SelectArray" directly from an SQL SELECT statement. For resource-safety reasons, we currently have it limited to reading of 1 Million string characters of data.

sRet = ExecutePS("SELECT * FROM PROD WHERE A1 LIKE '%CARD%';")
nColumns = Extract(sRet, 1)
nRows = Extract(sRet, 2)
For i = 1 to nRows
  sTemp = SelectArray(0, i)
  For j = 1 to nColumns
    sTemp = sTemp & ", " & SelectArray(j, i)
  Next j
  Crt sTemp
Next i
Or, getting more real and reporting on attributes of interest ..
sRet = ExecutePS("SELECT A0, A1, A2, A34 FROM PROD WHERE A1 LIKE '%CARD%';")
nRows = Extract(sRet,2)
For i = 1 to nRows
  sTemp = SelectArray(0, i) & ", " _
  & SelectArray(1, i) & ", " _
  & SelectArray(2, i) & ", " _
  & OConv(SelectArray(3, i), "MR2")
  Crt sTemp
Next i


Top     Next = Appendix: Summary Reference      Contents