Feeds:
Posts
Comments

Posts Tagged ‘javascirpt’

After creating TouchPaint I quickly realized that there were some users out there putting a lot of work into there pictures and they would lose them with a simple page reload.

There is an easy solution. Many of the latest generation of browsers including the IPad / iPhone, Safari 4+, Chrome, Firefox 3.5+ already support the HTML 5 Storage.

What HTML 5 Storage Provides

  • 5 megabytes of storage per domain
  • A SQL Light Database
  • JavaScript APIs to access the storage

I found this plenty for storing images however after going over the Webkit Data Storage Example I thought there might be something a little more approachable for Java developers. So I created a simple Data Access Object (DAO) that does the following

  • Intializes a database connection with a callback for successful attempts. Unsupported browsers see nothing.
  • Creates the site Database and tables on the first access.
  • Provides a Read and Update API

Lets look at each piece. If you want to see the raw JavaScript source you can find it here.

SQL Statements

First of all I keep the SQL statements which are prepared statements all together in a JavaScript map. This keeps the DAO pretty clean and it makes the SQL easy to update.

    var sql = {
      CREATE : "CREATE TABLE paintings (id REAL UNIQUE, json TEXT )",
      INSERT : "INSERT INTO paintings (id, json ) VALUES ( ?, ?)",
      UPDATE : "UPDATE paintings SET json = ? WHERE id = ?",
      GET : "SELECT json FROM paintings",
      COUNT : "SELECT COUNT(*) FROM paintings"
    };

Database Creation

New users will always be checked if the Database is intialized.

function initDB( _callback ) {
        try {
            if ( window.openDatabase ) {
                db = openDatabase("Storage", "1.0", "Painting Database", 2200000);
                checkIfDBInitialized();
                if ( !db ) {
                    alert( "Failed to open the database. Have you allocated enough space?" );
                } else {
                    if ( typeof _callback === "function" ) {
                        _callback.apply({}, []);
                    }
                }
            }
        } catch( error ) { 
            alert( "Error trying to open database : " + error );
        }
    }

I added the callback so those that want to then query or start polling for data can do so. A refactoring might also provide a failure case callback as well.

Check if Initialized

This code tries to see how many items have been put in the database. You can pull the count out if you choose and use it to assign numeric ids to future items.

  function checkIfDBInitialized() {
        db.transaction( 
               function(tx) {
                tx.executeSql( sql.COUNT, [],
                            function(tx, result) {
                                // do nothing 
                            },
                            function( tx, error) {
                               tx.executeSql( sql.CREATE, [],
                                              function(result) {
                                   // create our single row
                                   tx.executeSql( sql.INSERT, [ dataId, "[]" ]);
                             });
            });
        });
    }

Read

My example stores a JSON string which could be any text really.

function load( _callback) {
        db.transaction(function(tx) {
            tx.executeSql( sql.GET, [], function(tx, result) {
                if (result.rows.length > 0) {
                    var _row = result.rows.item(0);
                    var _json = _row['json'];
                    if ( typeof _callback === "function" ) {
                        _callback.apply( {}, [ _json ] );
                    }
                }
            }, function(tx, error) {
                alert( "Failed to retrieve paintings from database - " + error.message );
                return;
            });
        });
    };

Update

    function save( _json, _callback ) {
        db.transaction(function (tx) {
            tx.executeSql( sql.UPDATE, [ _json, dataId ], _callback);
        });
    };

Sample code :

Here the is an example which you may find at http://gregmurray.org/ipad/storage.

window.onload = function() {
    pictureDao.init( function() {
        // we have succesffuly loaded.
        pictureDao.load( function( text ) {
            var dataDiv = document.getElementById( "data" ).value = text;
        });
    });
};

function save() {
    var dataDiv = document.getElementById( "data" );
    pictureDao.save( dataDiv.value );
}

The window.onload fires and the database is initialized. If successful it will load text in the text area in the screen. Enter something and click save which results in the savefunction being invoked. The save function takes the text from the div and put it in local storage. You can verify by reloading the page.

That is pretty much it.

Resources :

Full source used in the examples in this page
What WG Web Storage Specification
HTML 5 Data Storage Example on gregmurray.org

Advertisements

Read Full Post »