You are browsing the archive for Carlo Kok.

New forum preview

October 14, 2013 in Uncategorized

In the last year, we’ve been looking into a better forum to replace Connect to overcome the issue it’s having with search and notifications and finally found one we liked: The new forum is Discourse and it will have all the previous posts from Connect. What we’d like to hear is your opinion of this forum and if everything works for you.

What this forum offers:

  • Better search results (for example: If you go into a category, it filters the search by that category)
  • Optional weekly mails about interesting topics
  • Proper notifications of replies

…and quite a few other features. Note that the current content is temporary and will be overwritten if/when we decide to move to this new forum. The forum can be found at talk.remobjects.com. At this moment all the posts up to July are visible. When we do the move to this new forum, all the connect posts will be copied over fresh, posts made to talk.remobjects.com now will stay. Our goal is to move to this forum as soon as we’re 100% sure there are no issues with it and all connect features are covered.

How “await” works

August 8, 2012 in .NET, Elements, Visual Studio

A while ago, marc wrote about our “await” keyword added in Oxygene 5.1. “Await” is a new language element for the .NET 4.5 framework that essentially lets you write sequential code without blocking the main thread. It’s actually pretty amazing, in that the compiler will split up your code so the asynchronous parts can run in a thread and then return execution to the main thread when it’s done. A simple example of this would be to do an HTTP request to our blog to grab the lastBuildDate field (the last time a new item was posted or updated).

The code you would write for that could look something like this:

method MainForm.button1_Click(sender: System.Object; e: System.EventArgs);
begin
  var lClient := new HttpClient();  { a }
  var lResponse := await lClient.GetAsync('http://blogs.remobjects.com/feed'); { b }
  MessageBox.Show(
    String.Format('The RemObjects blog was last updated at {0}', 
      XDocument.Parse(await lResponse.Content.ReadAsStringAsync).
      Descendants('lastBuildDate').FirstOrDefault():Value));
end;

There are actually two awaits in this block. The first one waits for the return of the HTTP request itself, the second one for the body.

If you wrote something similar without await and using synchronous APIs, your application would block and appear hung when the user clicks the button, since both parts of this request can take a while to execute. Pre-”await”, you could/should have opted to use existing asynchronous APIs, but they would have required to write code that is much more convoluted, involving anonymous methods and callbacks.

“Await” lets you write this code the “naïve” way, as simple, straight-forward sequential actions, and the compiler takes care of making things run in separate threads for you.

What really happens here is this (reformatted the names for readability):

method MainForm.button1_Click(sender: System.Object; e: System.EventArgs);
begin
  var worker := new MainForm.button1_Click_worker(sender, e, self);
  worker.Run;
  // your Button Click event is done here and your application is responsive right away.
end;

The “Run” method (actually called “d__0″) contains a state machine, which looks like it is a large “case” statement (again, slightly reformatted to make it more readable):

method MainForm.Button1_Click_worker.Run;
begin
  var lBeforeFirstAwait := false;
  try
    case fState of
      0: begin
       fState := -1; // If an exception occurs, we should never return here.
       lBeforeFirstAwait := true;
       lClient = new HttpClient(); { a }
           fAwaiter := self.Client.GetAsync('http://blogs.remobjects.com/feed').GetAwaiter(); { begin of b }
           if  fAwaiter.IsComplete then begin
             {pseudo} goto case element 1;
       end;
       fState := 1; 
       // It's not complete; this will make sure we jump to 
       // case element 1 when it is done. The awaiter 
       // will make sure it returns to the main thread.     
       fAwaiter.OnComplete(@Run);
       exit;
     end;
      1: begin // At this point we have the result of the HTTP request.
       fState := -1; 
       lResponse := TaskAwaiter<HttpResponse>(fAwaiter).GetResult(); { end of b }
       // Response is in. Here it pushes all values on the stack (before the next
       // await) and saves them in a tuple.
 
       fStackAtThisPoint := Tuple.Create('The RemObjects blog was last updated at {0}');
       // And waits again
       fAwaiter := lResponse.Content.ReadAsStringAsync().GetAwaiter();
       if fAwaiter.IsComplete then begin
         {pseudo} goto case element 2;
       end;
 
       fState := 2;
       // next time it jumps to the 2nd case element.
       fAwaiter.OnComplete(@Run);
       exit;
     end;
      2: begin // At this point we have the result of ReadOfStringAsync.
       fState := -1;
       MessageBox.Show(
           String.Format(
               Tuple<String>(fStackAtThisPoint).Item1,
               // restore the stack as it was before the await (just a string)
               XDocument.Parse(TaskAwaiter<String>(fAwaiter).GetResponse()).
               Descendants('lastBuildDate').FirstOrDefault():Value
            )
       );
 
       Builder.SetResult; // It's done. The builder is used to
       // turn this into a Task, if the outside method returns one.
     end;
    end;
  except
    on e: Exception do begin
      if lBeforeFirstAwait then raise; // If it fails before the first await
      // it should be returned like a regular exception.
      Builder.SetException(e); // else put it in the builder so a waiting task
      // gets the exception.
    end;
  end;

The nice part about this is that it all happens behind the scenes: the compiler turns the original method into a state machine, calls the right things and splits it up, making the original code retain its simplicity both in code and in reading. It’s a language feature (assisted by type support in the underlying runtime and framework) that is pretty unique, and the simplicity it provides is impossible to achieve without deep language integration.

Spell checking in code

July 19, 2012 in .NET, Elements, Linux, Mac, Oxygene, Windows

Last year marc wrote about our spell checking in code feature for Oxygene. This feature lets you continue using code completion after you made a typo in your code. The compiler will report an error as usual, pick the most likely choice from a list of possible identifiers and pretend that item was picked in the first place. The end result is that this code:

var s: Srting;
 
for i: Integer := 0 to s.Length -1 do begin
  s[i].
end;

will show code completion for the elements of the string, despite the wrongly spelled srting, and the compiler does the same thing, it shows an error for srting as usual, but using s will make it act like it’s a string.

There are a number of algorithms we could have picked to find the best matching item for this, so after some trial and error we picked the Damerau–Levenshtein distance and modified it a bit. Given two strings, this algorithm returns an integer indicating how many changes there are. Removal, adding or changes are counted as a single change, as are swapping two characters that follow each other (unlike the plain Levenshtein distance which only does removal, adding and changing, so swapping would count as 2). After some optimizations we came up with:

method DamerauLevenshteinDistance(string1: System.String; string2: System.String; aThres: Integer): System.Int32;
begin
  if string1 = nil then exit length(string2);
  if string2 = nil then exit length(string1);
  var s1l := string1.Length;
  var s2l := string2.Length;
  if ((s1l - s2l) > aThres) or 
    ((s2l - s1l) > aThres) then exit Int32.MaxValue; // if the length is that different there's no point in trying.
 
  if s1l > s2l then begin 
     // swap; make sure the smallest is always in string1, which will speed up the inner loop.
    var s := string2;
    string2 := string1;
    string1 := s;
    s2l := s1l;
    s1l := string1.Length;
  end;
  if aThres > s1l then aThres := s1l; 
 
  var lPrev := new Integer[s1l + 1];
  var lDist := new Integer[s1l + 1];
 
  for i: Integer := 0 to s1l do begin
    if (i <= aThres) then 
      lPrev[i] := i
    else
      lPrev[i] := Int32.MaxValue;
    lDist[i] := Int32.MaxValue;
  end;
 
  for j: Integer := 1 to s2l do begin
    var c := string2[j-1];
    lDist[0] := j;
 
    var min := Math.Max(1, j - aThres); // make sure we don't have to look back that much
    var max := Math.Min(s1l, j + aThres);
    if min > max then exit Int32.MaxValue;
 
    if min > 1 then lDist[min-1] := Int32.MaxValue;
 
    for i: Integer := min to max do begin
      var a := string1[i-1];
      if a = c then // the same, do not increase the value.
        lDist[i] := lPrev[i-1]
      else if (i < s1l) and (j < s2l) and (string1[i] = c) and (a = string2[j]) then  // swap
        lDist[i] := lPrev[i-1]
      else 
        lDist[i] := 1 + Math.Min(Math.Min(lDist[i-1], lPrev[i]), lPrev[i - 1]); // adding/removing
    end;
    var lTmp := lDist; // swap them; so instead of having to use a vector we use two arrays that swap around.
    lDist := lPrev;
    lPrev := lTmp;
  end;
  exit lPrev[s1l];
end;

It’s not the exact Damerau–Levenshtein distance implementation as found on Wikipedia, the original is slower and takes a lot more memory, but it’s based on it, with some ideas gotten from StackOverflow posts. It might not give the same result 100% of the time, but it works really well for us. We run this against a list of possible identifiers in scope where normally an unknown identifier error would occur, and return the lowest item. The Fix-It dialog shows the 10 possible matches below a given threshold. Now this same code can be used for a lot of things. You can even make a regular spell checker with this method.

Oxygene by Example – Threading

January 2, 2012 in Uncategorized

Threads are ways to run multiple things in parallel, at the same time. Each program in Oxygene has 1 or more threads, by default just one, which is the main thread, which is the one in which the gui code runs. Using multi-threading allows you to run something in the background, while keeping your main thread responding to actions from the user (in a gui application). It’s also useful when dealing with blocking operations, like sockets and data access. There’s no practical limit to the number of threads that run at once, it depends on the system resources (memory, cpu) how many will work at once.

Threading

Thread Class

The thread class represents the basis for all the other ways of working with threads. The thread API is simple to use. The constructor takes a delegate to run as the method for a thread, the “Start” method makes the thread start for the first time. “Join” waits for the thread to finish.

var lThread := new Thread(method begin
  var lClient := HttpClient;
  try
    var lResponse := lClient.Get('http://blogs.remobjects.com/feed/rss').Content.ReadAsString;
    Invoke(method begin // synchronize to the main thread
      LoadResponseData(lResponse);
    end); 
  except
    on e: Exception do  
      Invoke(method begin
        MessageBox.Show('Failed: '+e);
      end);
  end);
lThread.Start;

ThreadPool Class

The ThreadPool class offers static methods to run something when a CPU is available. It will create up to a certain number of threads (configurable, defaults to the number of CPU cores) and execute any task it gets given to it in order. Using the Thread Pool is simple. The QueueUserWorkItem method takes a delegate with an optional “state” arguments that gets passed to this delegate.

method MainForm.UpdateRssFeed;
begin
  ThreadPool.QueueUserWorkItem(method begin
    var lClient := HttpClient;
    try
      var lResponse := lClient.Get('http://blogs.remobjects.com/feed/rss').Content.ReadAsString;
      Invoke(method begin // synchronize to the main thread
        LoadResponseData(lResponse);
      end); 
    except
      on e: Exception do  
        Invoke(method begin
          MessageBox.Show('Failed: '+e);
        end);
    end;
  end);
end;

Task Class

The Task class was introduced with .NET 4.0 and introduces a new way to deal with threading. A task is an asynchronous operation. There are two classes, the Task class has no return value, while the Task<T> class does. Using the Task class is simple:

var lTask := new Task<String>(method begin
      exit lClient.Get('http://blogs.remobjects.com/feed/rss').Content.ReadAsString;
  end);
lTask.Start; // add to the default task thread pool and run on another thread.
 
lTask.ContinueWith(method (arg: Task<String>) begin
    try
      var lResponse := arg.Result;
      Invoke(method begin // synchronize to the main thread
        LoadResponseData(lResponse);
      end); 
    except
      on e: Exception do  
        Invoke(method begin
          MessageBox.Show('Failed: '+e);
        end);
    end;
  end);

Tasks can, in addition to this, also be waited upon with the “Wait” call, and the result can be read with the “Result” property.

Timers

There are 3 timer classes in .NET. One is in System.Windows.Forms.Timer, which does not run in a thread but runs at an interval in the main thread. The other two are about the same in features, except that the System.Timers.Timer has a synchronization object to talk back to the main form, while the System.Threading.Timer is a bit more lightweight. These classes offer a way to run code at an interval, for example every 5 seconds, or every 100 msec. In addition to thread, the version in the System.Threaded namespace allows specifying an initial interval.

var lTimer := new Timer(method begin
    Console.WriteLine('Timeout!');
  end, nil, 5000, 250);

This timer will keep running until the application closes, or the Dispose method is called. It first triggers after 5 seconds (5000 msec), then after that every 0.25 second.

Futures

The Oxygene language offers Futures which can optionally return and run either asynchronous, like a task, or delayed on the caller thread. Futures have the advantage that they’re a language element that are easily portable. Internally asynchronous futures use Task if it’s available, or the Theadpool class if it’s not. Futures are assignment compatible with Task/Task<T> on .NET 4, and Func/Action on 3.5.

var lAsync := new async lClient.Get('http://blogs.remobjects.com/feed/rss').Content.ReadAsString;
 
...
 
MessageBox.Show(lAsync);

When to use what

While opinions may vary on the subject, I tend to use the System.Threading.Timer for anything that runs multiple times at a constant interval. The futures map to Task or the thread pool depending on the .NET version, which I would use over those two. If for some reason I would not want to use a future, then I’d use the Task class when I’m developing against .NET 4 or above and have a short running thing to do, the Threadpool for short running things on versions that lack the Task class, and Thread for anything else.

Synchronization

Main Thread

When running in a thread, sometimes you have to tell the GUI that data is available. Updating the GUI from the thread is not safe, and usually leads to hard to find errors. The way to deal with this is using Windows Forms “Control.(Begin)Invoke”, or WPF/Silverlights’ “Dispatcher.(Begin)Invoke”. These apis take a delegate and will execute this delegate on the main thread. The Invoke methods will wait for the main thread to be done with the given task, the BeginInvoke methods will not and let the thread continue right away.

Object Access

Accessing a complex object is not generally a safe operation. Most objects in .NET are not thread safe, and will fail with strange errors when accessed from multiple threads at once. Do deal with this, you can use locking or interlocked access to simple fields.

Locking can be done with the “locking” statement. Locking is done on any object instance, generally this is an object not used for anything else.

type
  MySafeStringList = class
  private
    fLock: Object := new Object;
    fList: List<string> := new List<String>;
  public
    method Delete(s: string);
    method Add(s: string); 
    method GetCopy: List<string>;
  end;
 
method MySafeStringList.Delete(s: string);
begin
  locking fLock do fList.Remove(s);
end;
 
method MySafeStringList.Add(s: string); 
begin
  locking fLock do begin
    if not fList.Contains(s) then fList.Add(s);
  end;
end;
 
method MySafeStringList.GetCopy: List<string>;
begin
  locking fLock do begin
    exit new List<String>(fList);
  end;
end;

The locking statement will make sure only 1 thread at any given time have a lock on the object during the time the statement after it runs.

The other way to deal with values safely is with the Interlocked class. This class is limited to a few types and a few operations and makes it possible to exchange, compare, increment and decrement values safely.

Waiting for threads or resources

Sometimes it’s required to wait until some data is available, or to have the thread idle for a specific amount of time, but still make it possible to terminate it safely. An “EventHandle” is useful for this. There are two different event handles, one resets automatically, the other does not. These classes are called AutoResetEvent and ManualResetEvent. An event can have two states: Set and Unset. When it’s unset, the Wait operation will either timeout after a while, if a timeout is given, or wait for it to be set. The Set operation can be called from any thread and lets any possible waiting thread return with reset. At this point it will reset to Unset if it’s an AutoResetEvent, or stay set if it’s a ManualResetEvent. A useful use of this is to terminate a thread:

CheckForUpdatesThread = class
private
  fEvent: ManualResetEvent := new ManualResetEvent(false);
  fThread: Thread;
 
  method Work;
public
  constructor;
  method Stop;
  method CheckForUpdates;
end;
 
method CheckForUpdatesThread.CheckForUpdates;
begin
  ...
end;
 
 
method CheckForUpdatesThread.Work;
begin
  loop begin
    if fEvent.WaitOne(10000) then  // Wait for 10 seconds, returns true if it was set.
      exit;
    CheckForUpdates;
  end;
end;
 
method CheckForUpdatesThread.Stop;
begin
  fEvent.Set;
  fThread.Join; // wait for it to finish
end;
 
constructor CheckForUpdatesThread;
begin
  fThread := new Thread(@Work);
  fThread.Start;
end;

Concurrent Structures

.NET 4.0 introduces several new collections that are safe access from multiple threads. Among these structures are ConcurrentDictionary and ConcurrentStack. These have slightly different methods for adding and retrieving members than their non-thread safe counterparts but provide a fast way to work concurrently with shared data.

Original article

Oxygene by Example – Command line parsing

December 23, 2011 in .NET, Cooper, Elements, Mono, Oxygene, Uncategorized, Wiki

This is second article in my blog post series “Oxygene by Example”.

While working with command line arguments in Prism is quite simple, the “Main” method has an array of string that holds the value, it can become quite complex when having to parse options too. When having to work with those, it’s easiest to use the NDesk for Oxygene file. It’s a single file that can be added to any project (no need for a separate dll library). It was originally written in C# by Jonathan Pryor, we ported it to Oxygene so it can be embedded in an Oxygene project too.

The first step is to add NDesk.Options to the uses list, this is where the classes are defined. A general console application entry point looks like:

class method ConsoleApp.Main(arguments: array of String): Integer;
begin
  var lSourceUri: String;
  var lDestinationUri: String;
  var lSomeOption: Boolean;
  var lShowHelp: Boolean;
  var lOptionSet := new OptionSet(); 
  var lFiles: sequence of String;
 
  lOptionSet.Add("s|source=", "{filename or url} of source object", v -> begin lSourceUri := v end );
  lOptionSet.Add("d|destination=", "{filename or url} of destination object", v -> begin lDestinationUri := v end );
  lOptionSet.Add("o|someoption", "some binary option", v -> begin lSomeOption := assigned(v) end );
  lOptionSet.Add("h|?", "show help", v -> begin lShowHelp := assigned(v); end );
  try
    lFiles := lOptionSet.Parse(arguments);
  except
    on  Exception  do
      lShowHelp := true;
  end;
  if  (lShowHelp)  then begin
    lOptionSet.WriteOptionDescriptions(Console.Out);
    exit 1;
  end else  begin
    Console.WriteLine('Options supplied:');
    Console.WriteLine('Source: ' + lSourceUri);
    Console.WriteLine('Destination: ' + lDestinationUri);
    Console.WriteLine('Some option: ' + iif(lSomeOption,'ON','OFF'));
    for each el in lFiles do Console.WriteLine('Argument: '+el);
  end;
  Console.ReadLine();
end;

The OptionSet class is the main class for the options parser, first you have to define the different options by using the “Add” method. The first parameter defines what option it maps to. in “s|source=”, there are two bindings for this option, “s” and “source”, the | just separates them. The “=” is used to denote that the option takes a parameter. “s” is a single letter option, to use it one can use “MyApp -ssourcefile.text”, or “MyApp –source sourcefile.text”, the short options do not have a space, and a single dash, the long options have a space and two dashes.

The second parameter for Add is the description, when writing out the option list it will print this (see below), the last parameter is a delegate that gets called when it’s triggered. This delegate (in the cases above we use anonymous methods) has one parameter with the value passed. From these anonymous methods we set the options we define in the variables above it, that way we can read them later on.

The last step is lOptionSet.Parse(arguments), this will return a list of “rest” parameters, anything that’s not an option (or parameter to an option) will be in this list. It will raise an exception when there’s an error parsing arguments. We set the lShowHelp to true in this case, so we can later write the options to the console with WriteOptionDescriptions.

Using the Ndesk.Options classes makes parsing parameters a lot easier than doing it manually. The OptionSet classes have a lot more features, all of which are documented at the top of the source file Options.pas.

The original version of this article can be found in our wiki.

Oxygene by Example – Singleton

December 16, 2011 in Uncategorized

This is the first item in my series “Oxygene by Example”, this time about singletons.

Singleton classes are used when there’s only ever one instance of a class needed. They differ from Static Classes in that they have an actual instance, can implement an interface and you can use them as parameters to a method. There are different ways of writing singletons, but the easiest way is by using a readonly class variable:

type
  IObjectCache = interface
    method GetOrCreate(aName: string; aNeedNewValue: Func): T;
  end;
  GlobalObjectCache = class(IObjectCache)
  private
    fCache: Dictionary := new Dictionary;
 
    constructor; empty; // required to be private; so nobody can instantiate it
  public
    class property Instance: MySingleton := new MyObjectCache; readonly;
 
    method GetOrCreate(aName: string; aNeedNewValue: Func): T;
  end;
 
method GlobalObjectCache.GetOrCreate(aName: string; aNeedNewValue: Func): T;
begin
  locking fCache do begin
    var lValue: Object;
    if fCache.TryGetValue(aName, out lValue) then exit T(lValue);
    result := aNeedNewValue();
    fCache.Add(aName, result);
  end;
end;

Using the singleton is simple, GlobalObjectCache.Instance gives access to all instance members of the class:

  lblSystemName.Text := GlobalObjectCache.Instance.GetOrCreate(
    'ComputerName', -> Environment.MachineName);

The latest version of this article can be found Here.

Oxygene by Example

November 23, 2011 in Uncategorized

Last week I started on a series of articles called Oxygene by Example. They’re stored in the wiki at wiki.oxygenelanguage.com/en/Oxygene_by_Example and go over different problems while providing a solution written in Prism. So far I’ve written articles about:

  • Singleton – Single instance class
  • CommandLine – Parsing command line arguments and options
  • Threading – Working with threading in Prism
  • XML – Reading and writing XML files
  • Parsing – A simple expression tokenizer and parser
  • Visitor – A Visitor/Mutator pattern that can be used to do anything with a tree

Suggestions for other things I should write about are welcome, my ideas for further articles are the activator pattern, iterators, the observer pattern, working with linq, working with reflection, sockets and binary trees.

RemObjects (ECMA) Script

May 13, 2011 in .NET, Data Abstract, Linux, Mac, Mono, Windows

We recently finished a new version of RemObjects Script (Old version, New version), our open source implementation of the ECMAScript (JavaScript) language.

This new version is a complete rewrite that follows the exact rules of ECMAScript 5 to the letter, meaning it conforms to the ECMAScript 5 conformance test suite.

The dependency on the Microsoft Dynamic Language Runtime (DLR) has been dropped and thus speed has improved a lot. The engine is written in Delphi Prism with the Oxygene language, and is now licensed under the BSD license.

The engine was rewritten for two reasons: The original was written loosely based on EcmaScript 3, so the rewrite gives us full V5 support. The second reason was that the DLR was slowing it down a lot, and the abstractions and optimizations in the DLR are overkill for a language as simple as ECMAScript, with only a few internal types. The new version is built based on DynamicMethod and emits IL directly, making it very fast to run.

The RemObjects Script project is a key part of the Business Rules Scripting support in our Data Abstract for .NET product. Just as we released our Internet Pack library as open source, we do the same with RemObjects Script. This means you can freely use RemObjects Script in your Delphi Prism or any .NET project to add automation to your projects, too.

The usage instructions can be found at Using RemObjects Script.

MonoDevelop templates for the Mac

November 4, 2010 in Elements, iOS, Mac, MonoDevelop, MonoTouch, Oxygene, short, Uncategorized

For our MonoDevelop/Mac users we’ve created some new templates for MonoMac and MonoTouch. These are up to date templates that match the C# versions and let you write MonoMac (free) and MonoTouch (commercial) applications.

To install them, open MonoDevelop, select the Tools/Add-in Manager menu, click Repositories and add

https://secure.remobjects.com/api/monodevelop/mac/

to the list of repositories. Then select the Install Add-Ins… button and select the new templates from the update list.

Complete instructions and other extras for Prism can be found at http://remobjects.com/prismextras

Accessing a Data Abstract Server from Javascript

June 17, 2010 in .NET, Data Abstract

One of the client platforms for Data Abstract that has so far received little attention are JavaScript based web clients.

This morning I wrote a simple JavaScript (dojo toolkit based) web application that talks to an expanded PCTrade Sample Server. It leverages the JsonMessage to talk to the server, using JavaScript code for the simple service generated with Service Builder. The Dojo Toolkit btw is a very nice toolkit for writing javascript web applications.

 

Click on the image to start the video:

Start the video

Details

The Data Abstract Server sample contains a custom ExtendedHttpDispatcher implementation that serves the files in the javascript/ directory part of the sample, so acts like a regular web server when accessing http://127.0.0.1:8099/javascript, sending the files as-is, like a regular web server. The index.html file contains the JavaScript code, part of which is created with Service Builder, using the Tools/CodeGen/JavaScript menu on the Data Abstract Simple Data Service RODL.

Note that due to JavaScript security, the sample only works when accessing it from the same URL as the service itself.

The service provides 2 methods interesting for this web interface:

  • GetSchema: Returns the schema as an xml, used to populate the tree view on the left
  • SimpleGetData: GetData implementation that returns the data in an array of array of string with some Schema information.

The JavaScript application first asks for the schema, and uses XML DOM to find the names of all DataTables and their columns. When clicking a data table it changes the text area to the DA SQL select statment for that table. The “Execute Query” button calls the SimpleGetData service api, and when the callback for the response occurs, fills the grid with the returned data.