Uday Pratap Singh « Intelligrape Groovy & Grails Blogs
Subscribe via E-Mail:

Uday Pratap Singh

Groovy Follower, Grails Learner, GORM Lover, Spock Jedi and PhoneGap explorer.        uday@intelligrape.com , https://twitter.com/meudaypratap, http://in.linkedin.com/in/meudaypratap

Posts by Uday Pratap Singh:

  • Creating database in Phonegap

    24 Sep 2012 in Phonegap

    Currently I am building a mobile app using Phonegap. In my project I need to store the data into the database and refresh it with server time to time.

    Phonegap have the Storage API to do this. Storage API is based on the W3C HTML5 webdatabase. So we just need to create the database and corresponding table according to the webdatabase specification e.g;

    var db = openDatabase("myApp", 1.0, "App database",200000)
    

    Now to create tables and insert data into it using this db instance

    db.transaction(function(transaction){
        transaction.executeSql("CREATE TABLE user (username Integer default NULL, UNIQUE(username));");
        transaction.executeSql("INSERT INTO user (username) values ('uday');")
    })
    

    Now to get the data from this table we will simply write the select query. The executeSql method has its own success and failure callback method. Success callback gives the result set from the query e.g;

    db.transaction(function(transaction){
        transaction.executeSql("SELECT * from user where username=?",['uday'],successCallback,function(e){
           console.debug("some error") 
       })
    })
    
    function successCallback(transaction,results){
        for (var i = 0; i < results.rows.length; i++) {
            var username = results.rows.item(i).username; 
           // Some code
        }
    }
    

    The executeSql method takes four argument, first is the query, second array of values, if needed in the query, third success callback, which returns the result of query and last one error callback.

     

    Hope it helps
    Uday Pratap Singh
    uday@intelligrape.com
    https://twitter.com/meudaypratap
    http://in.linkedin.com/in/meudaypratap

  • Dynamically changing select value of jQuery Mobile select box

    jQuery mobile gives you a very beautiful UI which is compatible with all popular mobile device platforms and i must say its very easy to learn as well.
    It gives you a very nice select menu instead of typical select box that we see on our web site, for this we just need to add attribute “data-native-menu” in our select and we are done, e.g;

    <select name="reminderSettings" id="reminderSettings" data-native-menu="false">
    <option value="1" selected="selected">1 day before</option>
    <option value="2">2 days before</option>
    <option value="3">3 days before</option>
    <option value="5">5 days before</option>
    </select>
    

    But the problem occurs when we need to change the selected value dynamically. Usually we write the following code to change the selected values of select box.

    function setOptionValue(value){
      var reminderSettings = $("#reminderSettings");
      reminderSettings.val(value).attr('selected', true).siblings('option').removeAttr('selected');    
    }
    

    It will definitely change the selected value but the UI will not reflect it, to reflect this on the UI as well we need to refresh our select box.

        reminderSettings.selectmenu("refresh", true);
    

    We need to add the above line after changing our select value and its done.

     

    Hope it helps
    Uday Pratap Singh
    uday@intelligrape.com
    https://twitter.com/meudaypratap
    http://in.linkedin.com/in/meudaypratap

  • Download and store external files to mobile in phonegap

    23 Sep 2012 in Phonegap

    In my current phonegap project I need to give the offline support of the application. It means I have to store all the external files on the device and refer the file from local device path. So to do this I need to know how I can store external files on device using phonegap.
    Phonegap comes with very handy FileTransfer API which allows developer to download any file from url and store it on the device. For storage we need to have the full path where we want to store the file. Lets take an example.

    function storeIntelligrapeLogo(){
      var url = "http://www.intelligrape.com/images/logo.png"; // image url
      window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function (fs) {
          var imagePath = fs.root.fullPath + "/logo.png"; // full file path
          var fileTransfer = new FileTransfer();
          fileTransfer.download(url, imagePath, function (entry) {
                   console.log(entry.fullPath); // entry is fileEntry object
          }, function (error) {
                   console.log("Some error");
          });
       })
    }
    

    This is it, we have downloaded the file and its stored in “/Users/intelligrape/Library/Application Support/iPhone Simulator/5.0/Applications/CF2A9018-49B9-4DE6-91FC-EA76CB435FC8/Documents/logo.png” on my system (As I run the code on simulator).

     

    Hope it helps
    Uday Pratap Singh
    uday@intelligrape.com
    https://twitter.com/meudaypratap
    http://in.linkedin.com/in/meudaypratap

  • Get the full application storage path in Phonegap

    23 Sep 2012 in Phonegap

    Phonegap gives me the freedom of creating mobile app with my existing knowledge of HTML, CSS, Javascript. It has a very nice javascript API to access the device features like camera, contacts, file etc.

     

    There are times when you need know where your files are stored. Specially when you are providing the offline support of the app and want to store the files like images and then show the images from local system whenever user goes offline. I also had the same requirement in my project, let see how I did it for iphone

    window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function (fs) {
                 console.log(fs.root.fullPath)
    //On simulator it will return something like /Users/intelligrape/Library/Application Support/iPhone Simulator/5.0/Applications/CF2A9018-49B9-4DE6-91FC-EA76CB435FC8/Document
    })
    

    You can use this path in various cases like creating the full path of your files.

     

    Hope it helps
    Uday Pratap Singh
    uday@intelligrape.com
    https://twitter.com/meudaypratap
    http://in.linkedin.com/in/meudaypratap

  • Pessimistic locking in Grails

    03 Sep 2012 in GORM&Grails

    We already know that by default Grails scaffold comes with Optimistic locking and it is achieved by version field. Now lets see how Pessimistic locking is achieved in Grails.
    Grails has a built in method to acquire lock on object. To acquire a lock we will do something like following

    Book book = Book.get(1)
    book.lock()
    

    The above code will fire 2 queries one for getting the object and other for taking the lock on it, something like as follows

    Hibernate: select book0_.id as id1_0_, book0_.version as version1_0_, book0_.name as name1_0_, book0_.price as price1_0_ from book book0_ where book0_.id=?
    Hibernate: select id from book where id =? and version =? for update
    

    or we can do both the tasks in single go by using the static lock method

    Book book = Book.lock(1)
    

    The above code will fire only one query

    Hibernate: select book0_.id as id1_0_, book0_.version as version1_0_, book0_.name as name1_0_, book0_.price as price1_0_ from book book0_ where book0_.id=? for update
    

    Whenever there is simultaneous updations of an object occurs it throws StaleObjectException.

     

    Hope it helps
    Uday Pratap Singh
    uday@intelligrape.com
    https://twitter.com/meudaypratap
    http://in.linkedin.com/in/meudaypratap

  • Discriminator in Grails inheritance

    03 Sep 2012 in Design Pattern&GORM&Grails

    Whenever I have the use case of inheritance in my Grails application I prefer to have the single table for all the classes, to avoid joins and multiple save statement. But one thing I dont like about this is its class discriminator which have the full class name in it. I dont find it much readable when looking into the sql.

     

    Grails provide cool mapping to customise the discriminator in Grails inheritance. To explain this I am taking the example  of  my last blog . So to change the value of discriminator I just need to add the discriminator mapping in every sub class and give them some unique identification value

    static mapping = {
            discriminator "TextBlog"
        }
    

    Now the class discriminator will store “TextBlog” rather than full class name e.g; com.intelligrape.example.TextBlog.

    After doing this I change the discriminator column name because its not actually storing the class, so I add following mapping to my base class to change column name.

    static mapping = {
            discriminator column: "type"
        }
    

    After doing this the column name will change from “class” to “type”.

     

    Hope it helps

    Uday Pratap Singh
    uday@intelligrape.com
    https://twitter.com/meudaypratap
    http://in.linkedin.com/in/meudaypratap

  • Inheritance in Grails

    03 Sep 2012 in Design Pattern&GORM&Grails

    In Grails we can have inheritance with abstract base class as well as persistent base class. Lets take an example to explain this.(All the classes are in the package com.intelligrape.example)

    class Blog{
        String authorName
        static constraints = {
             authorName (nullable:false)
        }
    }
    class TextBlog  extends Blog{
        String textContent
        static constraints = {
             textContent (nullable:false)
        }
    }
    
    class PodCast  extends Blog{
        byte[] content
        static constraints = {
              content (nullable:false)
        }
    }
    

    By creating such class structure Grails will create a single table and all the three classes will share it. Our table will look like as follow

    +--------------+--------------+------+-----+---------+----------------+
    | Field        | Type         | Null | Key | Default | Extra          |
    +--------------+--------------+------+-----+---------+----------------+
    | id           | bigint(20)   | NO   | PRI | NULL    | auto_increment |
    | version      | bigint(20)   | NO   |     | NULL    |                |
    | author_name  | varchar(255) | NO   |     | NULL    |                |
    | class        | varchar(255) | NO   |     | NULL    |                |
    | text_content | varchar(255) | YES  |     | NULL    |                |
    | content      | tinyblob     | YES  |     | NULL    |                |
    +--------------+--------------+------+-----+---------+----------------+
    

    We can see that other than the declared fields Grails created three more fields
    id : Auto increment field, used as an identifier and managed by Grails itself
    version : Used for optimistic locking, increments each time when object is updated
    class : Discriminator column used to identify what specific type of blog is associated with given row e.g; com.intelligrape.example.TextBlog

    There is a drawback with this approach, as you can see in the table, column text_content and content fields are nullable true although we have defined them as nullable false in domain class. Consequence of storing all kind of blog data in single table is that we can’t have non nullable columns in sub classes but because of single table, joins are not fired and our queries will be faster. Second disadvantage could be the long discriminator, which makes it difficult to read the data of a particular class in sql.

    If you dont like having single table for all the data, Grails give you freedom to create multiple tables for each class. You just need to add the following mapping block in base class

    static mapping = {
            tablePerHierarchy false
    }
    

    Now you can see three different tables for each class. But the major drawback in this approach is whenever you save the instance of sub-class it executes two queries for save like following

    Hibernate: insert into blog (version, author_name) values (?, ?)
    Hibernate: insert into text_blog (text_content, id) values (?, ?)
    

    Second drawback is again on query performance. Whenever you execute some GORM query for fetching data it executes join query e.g; TextBlog.list() method will have the following join query

    Hibernate: select this_.id as id2_0_, this_1_.version as version2_0_, this_1_.author_name as author3_2_0_, this_.text_content as text2_4_0_ from text_blog this_ inner join blog this_1_ on this_.id=this_1_.id
    

    Now its our decision which makes more sense to our application.

    Hope it helps
    Uday Pratap Singh
    uday@intelligrape.com
    https://twitter.com/meudaypratap
    http://in.linkedin.com/in/meudaypratap

  • Pre populating database in phonegap app

    03 Sep 2012 in Phonegap

    Currently I am working on developing mobile app using Phonegap. Phonegap comes up with very nice javascript methods to access phone specific api and the developer like me who have fair knowledge of javascript HTML and CSS can learn it very quickly.

    My app required bundling the database into the app but there is no straight forward way in Phonegap to do this but I found a way to do this.
    I added “app.sql” file in my “www” folder and get the text of this file. My app.sql looks something like this

    CREATE TABLE 'category' (categoryId long NOT NULL, name varchar(255) NOT NULL);\n
    INSERT INTO 'category' VALUES(1,'cat_1');\n
    INSERT INTO 'category' VALUES(2,'cat_2');\n
    INSERT INTO 'category' VALUES(3,'cat_3');\n
    INSERT INTO 'category' VALUES(4,'cat_4');\n
    

    I am using jquery in my example

    function runInitialSetup() {
       var filePath = "app.sql";
       $.get(filePath, function (response) {
             var statements = response.split('\n');
    
             var shortName = "database";
             var version = '1.0';
             var displayName = 'App Database';
             var maxSize = 200000; //  bytes
             db = openDatabase(shortName, version, displayName, maxSize);
    
             db.transaction(function (transaction) {
                jQuery.each(statements, function (index, value) {
                    if (value != '') {
                        transaction.executeSql(value, [], successHandler, function (e) {
                            console.log("Error executing sql " + value)
                        });
                    }
                });
             });
        });
    }
    

    I executed above method whenever the app is installed first time.

     

    Lets see whats happening in the above example. I read my app.sql file which was bundled in the app and the response I got is the text, so I split the content on newline character. There is the assumption that each sql statement is separated with newline character and the content in sql do not have the newline character.

     

    Then I made the database connection and executed each statement to setup the database.

     

    You can read any text file bundled in your app build. You can always read the content from your bundled app but never think of writing files because its not possible.

     

    Hope it helps

    Uday Pratap Singh
    uday@intelligrape.com
    https://twitter.com/meudaypratap
    http://in.linkedin.com/in/meudaypratap

  • Optimistic locking strategy in Grails

    01 Sep 2012 in Database&GORM&Grails

    In Grails optimistic locking is achieved by version property . The Grails Domain classes has a built in property called “version”. This property can be used for optimistic locking. Although you can remove this property

    static mapping ={
          version false
    }
    

    but its not a very good practice. The initial value of version field is 0 and Grails automatically increments it by 1 every time the object is updated. This property helps to identify whether the currently updating object has already been updated or not.

     

    Suppose we have a Book domain and its corresponding BookController the default Grails scaffold update action has code something like as follows

    if (version != null) {
                if (book.version > version) {
                    book.errors.rejectValue("version", "default.optimistic.locking.failure",
                            [message(code: 'book.label', default: 'Book')] as Object[],
                            "Another user has updated this Book while you were editing")
                    render(view: "edit", model: [book: book])
                    return
                }
            }
    

    As we can see it checks the current version of the object with the version got from request. If the current version of object is greater, it injects the error into the object and object is not saved.

     

    Hope it helps
    Uday Pratap Singh
    uday@intelligrape.com
    https://twitter.com/meudaypratap
    http://in.linkedin.com/in/meudaypratap

  • Grails 2.1 command line alias

    18 Aug 2012 in Grails

    I am a linux user and like to do everything on command line, I find it more productive. Anytime I need to write long command or use any command frequently, I always create an alias for that, for example while running the test cases I need to run the command so I created alias for this in my bashrc

    alias testunit='grails test-app unit:'
    

    But there are so many and my bashrc keeps on increasing (though I am least concern of this as I have separate file for this). Here is the good news, now grails 2.1 has its own support for aliases so I created the alias for running tests

     grails alias unit test-app unit:
    

    and now I can run my test by typing

    grails unit
    

    Actually grails reads and writes aliases to the file

    .grails/.aliases

    Now I can create the commonly used grails aliases in this file and share it with my team.
    Isn’t it cool. Hope it helps


    Uday Pratap Singh
    uday@intelligrape.com
    https://twitter.com/meudaypratap
    http://in.linkedin.com/in/meudaypratap