Navigation:  The Server in depth > Server Extended Settings > AppServer - Web Scripts >

How to write a web script

Previous pageReturn to chapter overviewNext page

Please note that technical support for writing scripts is not provided with the standard support packages, but is available on a consulting basis.

 

Technically every such application internally uses the new TnxsrBaseWebApplication component, which implements a scriptable web environment. It also support SSL and BASIC authentication against the users defined on the server. As you can see, defining such an application is pretty simple, all that is needed is a name, a base directory and a port. The extension for server scripts is .nxscript but the web server will serve any file within the base directory. While the feature is called "AppServer - Web Scripts" it can of course be also a set of loose web pages that you want to provide to a client.

 

The NX Server ships with a very simple sample "application" called WebApp1 located as a sub folder in the server directory. All of the examples used in this article are included in that folder as well.

 

The Basics

 

Let's take a look at the simplest of all examples, helloworld1.nxscript.

 

<%

begin

%>

Hello world!

<%

end.

%>

 

As you can see the script is essentially a mix of a pascal program and a web site separated by the commonly used <%%> "tags". For above to run, add the WebApp1 folder as an application (let's say port 90) and set it to active. Don't forget to press the "Save Settings" button. Once it's done the application name should be in bold green which means the app is up and running. Now open a browser and point it at http://localhost:90/helloworld1.nxscript. Unless your firewall blocks that port you should now see "Hello world!".

 

The scripting engine used is a modified engine, which is for example widely used in InnoSetup. The version built into NexusDB is giving scripts access to the server infrastructure, but also allows to build database client application running directly on the built in server engine. More on that later. Let's start with the simple but important things.

Manipulating the resulting web page

 

The first one is the ability to write directly to the response buffer. For this purpose every script has an implicit class instance Output: TnxSimpleOutputCache which can be used to manipulate the output. These are the (public) members which hopefully I don't need to explain.

 

type

 TnxSimpleOutputCache = class(TnxComponent)

 public

   procedure Write(const aText: Variant);

   procedure WriteLn(const aText: Variant);

   procedure Clear;

   procedure SaveToFile(FileName: string);

   procedure Flush;

   property Text: string

 end;

 

Here's another possible way to create the same output for the hello world example:

 

<%

begin

%>

Hello

<% Output.Write('wor'); %>

ld!

<%

end.

%>

 

Easy isn't it? Let's look at how to access the databases on the server.

 

Accessing NexusDB

 

The fastest way to access data on a server is to access the internal server engine. For this purpose the scripting engine exposes this internal engine as ServerEngine: TnxsrServerEngine variable. The full class is exposed thus you have full access to all server engine properties. The engine also exposes all relevant DB classes thus you can easily define and create NexusDB classes in a script. The following script opens a table Test in database Test and dumps the first field to the screen.

 

<%

var

 aSession: TnxSession;

 aDB: TnxDatabase;

 aTable: TnxTable;

begin

 aSession:=TnxSession.Create(nil);

 aDB:=TnxDatabase.Create(nil);

 aTable:=TnxTable.Create(nil);

 try

   aSession.ServerEngine:=ServerEngine;

   aSession.Active:=true;

%>

Session opened<br>

<%

   aDB.AliasName:='Test';

   aDB.Session:=aSession;

   aDB.Open;

%>

Database opened<br>

<%

   aTable.TableName:='Test';

   aTable.Database:=aDB;

   aTable.Open;

   while not aTable.Eof do

   begin

     Output.Writeln(aTable.Fields.Fields[0].AsString);

     aTable.Next;

   end;

%>

Database opened<br>

<%

 finally

   aDB.free;

   aSession.Free;

 end;

end.

%>

 

As you can see that looks pretty much identical to a Delphi application. There are two caveats here:

 

the scripting engine does not support default properties, thus you need to access the full property path. You can see that clearly in the access to the Fields property.

while in a normal application you wouldn't really need to free the created classes (as it terminates anyway) this is MANDATORY in scripting. Every class instance that you create has the lifetime of the Web application, thus as long as it the application is active the instance will stay around. So be very careful as a small leak can create havoc on the server.

 

The scripting engine exposes most of the NexusDB symbols to scripts, this includes all types, classes and procedures in nxllTypes, nxllComponent, nxsdServerEngine, nxsrServerEngine, nxsdDataDictionary, nxdbBackupController and nxsrSystemStorage, as well as most of the Delphi Types, Classes and Sysutils units. This should allow you to achieve pretty much everything you ever want in terms of single script functionality.

 

Server Sessions

 

Even though running single scripts is already a great thing to have, the Web Application becomes even more powerful by supporting user sessions. Again this is achieved by surfacing an implicit instance of Server: TnxHTTPRequest.

 

type

 TnxHTTPRequest = class(TnxLoggableComponent)

 public

   // URL encode a string

   function ServerEncode(aString:string):String;

   // URL decode a string

   function UrlEncode(const aString: String): String;

   // get a url request attribute

   function Request(const what: String): Variant;

   // get a user session var.

   function GetVar(const Name: String): String;

   // set a user session var.

   procedure SetVar(const Name, Value: String);

 

   // access to the raw HTML request split to lines

   property RawHeaders: TStringList read fRawHeaderInfo;

   // access to the parsed HTML headers as ini value pairs

   property Headers: TStringList read fHeaderInfo;

   // access to cookies as ini value pairs

   property Cookies: TStringList read fCookies;

   // returns the request URL

   property RequestDocument: string read fRequestDocument;

   // access to the reply headers as ini value pairs

   property ReplyHeaders: TStringList read fReplyHeaders;

   // HTTP Version

   property HTTPVersion: string read fHTTPVersion;

   // the full raw request

   property RawRequest: string read fRawRequest;

 end;

 

Not only does this function allow access to the raw and preprocessed information of the html request, but note the SetVar and GetVar functions, which allow you pass information from within a user session. The object also allows you read/write access to cookies.

 

An example of using the Server.SetVar/GetVar combination to handle sessions, please take a look at the sources of the NexusDB Remote Administration (Admin root folder). Yes, the Remote Administration is nothing else than a session supporting Web Application, which is always defined for a NexusDB server.

 

Some more things worth to know

 

If you have now looked at the remote administration you have probably seen that there are two more predefined Instances: NxServer: TTNXServerLink and SystemDB: TnxSystemDatabase. The first is a flattened simplified access to all the components registered with the ServerEngine. We've chosen to provide this TTNXServerLink class for future easy access from other programming languages (e.g. C#). The latter is giving access to the servers system database which holds things like registered assemblies, the installed web applications, etc.

 

Conclusion

 

While we know that this functionality is not needed by everyone we do believe that it is a unique feature that will hopefully help a lot of customers to achieve more flexibility and integration for their applications. No need for IIS + ODBC or PHP, just use the server directly.

.