Smart Mobile Studio
  • News
  • Forums
  • Download
  • Store
  • Showcases
    • Featured demos
    • The Smart Contest 2013, Round 1 – Graphics
  • Documentation
    • Get the book
    • System requirements
    • Prerequisites
    • Getting started
      • Introduction
      • Application architecture
      • The application object
      • Forms and navigation
      • Message dialogs
      • Themes and styles
    • Project types
      • Visual project
      • Game project
      • Console project
    • Layout manager
    • Networking
      • TW3HttpRequest
      • TW3JSONP
      • Loading files
  • About

Real data, talking to sqLite

Most modern browsers supports some form of local database engine. For webkit and mozilla based browser that local database is sqlite, which (behind the scene) is built into the actual browser program. Internet explorer does not support this api but have other mechanisms for local data manipulation, including the ability to store data as XML.

In short, there are several database standards, but the most known are: IndexDB and Web SQL database. Before we dig into the nitty gritty of these things, let’s familiarize ourselves with the landscape.

Security and size restrictions

Browser vendors are constantly challenged when it comes to security. Hackers have proven that even the slightest weakness in security can be exploited, often with costly consequences for the unsuspecting user. Since this is the case you are not allowed to simply access or create a database anywhere you want. When you create a database the file is kept in a secure section of the browser cache and is explicitly linked to your web applications url.

There is also the case of database size, which in most browsers is set to between 5 and 10 megabyte by default. If the user needs more data he or she will have to manually change this. While 5 megabytes sounds ridicules to a delphi programmer, who is used to handle gigabytes of data in a plethora of different database engines – the browser database api was not created to be your central database solution. It was created to allow you to cache data between your web-apps and your server.

Removing the restrictions using phonegap

The web apps you create with Smart Mobile can be wrapped with a system called phonegap. Phonegap takes you generated html, javascript and css files (and any other files connected to your html) and injects it into a real .exe file for both Android and iOS. This real .exe file creates it’s own browser instance, puts the browser in full-screen – and disables the security restrictions that public browsers imposes on you. Once wrapped, you can create persistent (non cached) databases of any size. Or at least without the 5 to 10 megabyte limitation.

Using a central server

In our typical scenario we have a RPC server which supports JSON (the format browsers use to send data, a bit like XML only more compact) messages. We like to use remobjects remoting framework, but you should be able to use the standard delphi webservice components to achieve the same thing – or indeed the excellent delphi on rails toolkit by Henri Gourvest.

So on our server we would expose an interface that external client apps (web or native) can call to extract data.  Below is a hypothetical variant of such an interface. Note: this is just an example, there are must better ways of handling remote databases, but we have to start somewhere.

type
  IMyDataService = interface
    function  GetTopId: Int64;
    function  GetCountBetween: Int64;
    function  ReadRowsFromTop(const aCount: Integer):String;
    function  ReadRowsFromOffset(const aRecId: Int64):String;
    procedure UpdateRows(const aRowData: String; const aAppend: Boolean);
  end;

This would be the bare minimum you could use to mirror a small news-feed between a client and a mobile app. The functions would return the database rows in JSon format. Now lets go through a possible chain of communication between the server and your mobile app.

When you mobile application starts, it will call getTopId() to get the current topmost record-id from the database server. It will then compare the number it get back to it’s own “last known id”. If they are different, you know more news have been added on the server and that your local database needs to be updated.

If you want to know the exact number of records that have been added since your last update, you can call getCountBetween(), sending in the record-id of your last record. The server would return the number of rows added to the database since that number was “first”.

Based on this information, your web app would check that the amount of new records dont exceed the storage capacity of the database and ultimately call either readRowsFromTop() or readRowsFromOffset() if you want a spesific data range.

Again I must stress that this is not a very efficient way of doing things, it serves as an example of how you could sync a client with a server, nothing more.

IndexDB

Note: As of writing Smart 1.0 has just been released. It provides the foundation that we are going to build on, but sadly there was not enough time to add pre-made database components to this initial release. We have already started working on a TClientDataset class that will serve as the middle-man between cached updates from a server – and your local sqlite engine inside the browser. But as of writing the API is not ready.

In order to create a database we have to resort to some assembly code, which means javascript in our case. Creating a local database is quite easy. But handling javascript’s async nature in a linear way is not easy.


function w3_getIndexDB:THandle;
Begin
  result:=null;
  asm
   if (window.indexedDB) return window.indexedDB;
   if (window.webkitIndexedDB) return window.webkitIndexedDB;
   if (window.mozIndexedDB) return window.mozIndexedDB;
   if (window.msIndexedDB) return window.msIndexedDB;
  end;
end;

// Returns the request object
function w3_openIndexDB(const adbName:String):THandle;
var
 mEngine: THandle;
Begin
  mEngine:=getIndexDB;
  if (mEngine) then
  Begin
    result:=mEngine.open(adbName);
  end else
  result:=null;
end;

Now comes the tricky part, because we are really dealing with an objective database and not a sequential database. This means that each record is associated with a key and a datastore (which functions as a table). Since javascript is async, every operation we perform needs more infrastructure as well. So here is how you could open up a database and handle events:

var
  myDb:THandle;

begin
  myDB:=w3_openIndexDB('mydb');
  if (myDB) then
  begin
    myDb.onerror:=procedure (event:variant)
      begin
        //catch errors here
      end;
    myDB.onsuccess:=procedure (event:variant)
      begin
        //handle success codes here
      end;
    myDB.onupgradeneeded:=procedure (event:variant)
      begin
        //alter schema here, create tables (datastores) and setup key generators
      end;
  end;
end;

More to come soon! We are currently busy turning these things into proper objects so you don’t have to deal with this low-level stuff

8 thoughts on “Real data, talking to sqLite”

  1. Donovan says:
    24.04.2012 at 13:54

    Any news on this article?? I am very interested in testing database linked app

    Log in to Reply
    • Jon Lennart Aasenden says:
      25.04.2012 at 05:57

      Hi Donovan

      Yes it’s coming. The database units are our #1 priority next to finishing version 1.0. So the database units will be a download available to our customers straight after the product is released. On our list is also wrapping the sound API and providing a full phonegap wrapper. But right now focus is on the final pieces of the IDE.

      Log in to Reply
  2. AB says:
    17.05.2012 at 21:10

    For Client-Server communication, do not forget about http://mormot.net
    This is now a well established Client-Server ORM and SOA framework, including a strong security model, best speed possible, and interface-based services.
    We are currently prototyping direct client access from Smart, using plain Smart Object Pascal code, including authentication and strong security.
    See http://blog.synopse.info/post/2012/04/19/Smart%3A-mORMot%2C-from-Delphi-to-JavaScript about how we managed to code CRC32 and SHA256 in a Smart compatible way (this is more technical than with plain Delphi/FPC).
    It is full Open Source, working from Delphi 6 up to XE2, with a growing base of users.
    BTW, I’m not sure the MVC model of DoR is directly applicable to Smart clients – of course, the RESTful part is, but DoR interrest is not just JSON SuperObject over HTTP.

    I suspect you want to add more and more documentation to your project. Take a look at our open source tool SynProject: mORMot’s documentation is created with it. It is easy to use (at least for programmers), and powerfull to create technical docs, including source code, indexs, and links. See http://synopse.info/fossil/wiki?name=SynProject

    Log in to Reply
  3. AB says:
    18.05.2012 at 11:27

    I suspect that if you want your code to be PhoneGap ready, you would better add “window.openDatabase” to your w3_getIndexDB function. Or is PhoneGap mapping the window.indexedDB instance?

    Log in to Reply
    • Jon Lennart Aasenden says:
      18.05.2012 at 12:14

      That will be handled by the driver. Things like checking for database support, gyroscope – all these things is up to the driver to handle. It is created when you app starts up after checking what browser you are running and it’s caps. So a phonegap driver is all that would be needed (and it would just override the webkit driver) to fill the phone gap so to speak 🙂

      Log in to Reply
  4. Justmade says:
    06.02.2013 at 02:35

    It seems it had been almost 1 years since this article published. Do you have any news for that? We would like to have a database front end that can work offline in tablets / mobiles.

    I already tested the connection to Remobjects SDK so more concert on the local database storage and accessibility. A TQuery like objects to handle local tables would be a great help. A TClientDataset class mentioned above is a great addition to make data sycn more easy.

    So we would like to know the status of the database handling of SMS before we can decide to go for this options for our new front-end. Thank you very much.

    Log in to Reply
    • Jon Lennart says:
      06.02.2013 at 13:03

      We have implemented webSQL (w3websql.pas) which provide the basic classes for using the browsers built in database. We are currently in the pipeline of porting DataSnap. Sadly we cant give an estimate for when that aspect will be ready. But using the websql classes is fairly straight forward – but field to control binding is still some time into the future.

      Log in to Reply
      • Justmade says:
        06.02.2013 at 15:25

        Thanks for your prompt answer. I had test the websql sample which work in android and chrome but not IE and FF (even the plug-in failed to work after FF17). The more important point is that it had stopped development in Nov 2010 and so have no future.

        http://en.wikipedia.org/wiki/Web_SQL_Database

        At least it can be used in both tablet/mobile environment and desktop too for now.

        I am also wondering what is the most efficient way to transfer a dataset result from remobjects server to SMS client.

        A Delphi dataset like objects will be very useful in both case.

        Log in to Reply

Leave a comment Cancel reply

You must be logged in to post a comment.

Pages

  • About
  • Feature Matrix
  • Forums
  • News
  • Release History
  • Download
  • Showcases
    • The Smart Contest 2013, Round 1 – Graphics
  • Store
  • Documentation
    • Creating your own controls
    • Debugging, exceptions and error handling
    • Differences between Delphi and Smart
    • Get the book
    • Getting started
      • Introduction
      • Local storage, session storage and global storage
      • Application architecture
      • The application object
      • Forms and navigation
      • Message dialogs
      • pmSmart Box Model
      • Themes and styles
    • Layout manager
    • Networking
      • Loading files
      • TW3HttpRequest
      • TW3JSONP
    • Prerequisites
    • Real data, talking to sqLite
    • System requirements
    • Project types
      • Visual project
      • Game project
      • Console project

Archives

  • December 2019
  • December 2018
  • November 2018
  • July 2018
  • June 2018
  • February 2018
  • September 2017
  • April 2017
  • November 2016
  • October 2016
  • September 2016
  • April 2016
  • March 2016
  • January 2016
  • October 2015
  • September 2015
  • July 2015
  • April 2015
  • January 2015
  • December 2014
  • October 2014
  • September 2014
  • August 2014
  • July 2014
  • June 2014
  • March 2014
  • February 2014
  • January 2014
  • December 2013
  • November 2013
  • October 2013
  • August 2013
  • July 2013
  • June 2013
  • May 2013
  • April 2013
  • March 2013
  • February 2013
  • January 2013
  • December 2012
  • November 2012
  • August 2012
  • July 2012
  • June 2012
  • May 2012
  • April 2012
  • March 2012
  • February 2012
  • January 2012
  • November 2011
  • October 2011
  • September 2011

Categories

  • Announcements (25)
  • Developers log (119)
  • Documentation (26)
  • News (104)
  • News and articles (16)

WordPress

  • Register
  • Log in
  • WordPress

Subscribe

  • Entries (RSS)
  • Comments (RSS)
© Optimale Systemer AS