Sachin « Intelligrape Groovy & Grails Blogs
Subscribe via E-Mail:

sachin

http://www.intelligrape.com/blog

Grails Enthusiast, Technology lover and a self confessed foody... ;-)

Posts by sachin:

  • Using Git Rebase

    22 Jan 2012 in git

    Working on a cool project, doing cool and unusual stuff has its own charms and challenges. For doing cool things, you need cool tools to play with and Git surely is one of the coolest ones around. One of the many powerful features of git is rebase.

    While working on a large project, you almost always develop your feature on a new branch, and for a large enough feature/requirement, It could take up to month or more to deliver it.

    Lets consider a scenario where you need to begin on a new feature and you create a separate branch,(coolNewStuff) , off your main integration branch, (master).

    New Branch from master

    While you were working on the stuff, other guys in your team were pushing and integrating their stuff into the master branch. As a result master branch moved ahead and there were loads of commits and other stuff added to it.

    Now before pushing your cool stuff into master, you would need to pull in the changes in the master to your current(coolNewStuff) branch. You could easily do that using

    git pull origin master
    

    Resolve conflicts. commit changes and merge this branch with master.

    Nothing wrong with that actually, except that it creates a lot of intermingled commits in the branch, and it won’t give a clear roll back point.

    What you actually want to do is put your work on top of the existing master branch as a separate commit so that you get a clear roll back point in case something goes wrong.

    You want your changes of coolNewStuff branch on top of current master head, you don’t want master on top your coolNewStuffBranch.


    Enter Rebase.

    What rebase allows you to do is rewrite the history of your branch. You can actually pull in the changes from master branch place them above the master branch, you branched out off  (some 30-45 days back) and then place all the stuff you developed (all commits you made since the day you branched off) on top of this new pulled in changes from master. So, this looks like…

    All you need to do is on the coolNewStuff branch call

    git rebase master
    

    This will start your rebasing process. It will basically collect the changes you made since you branched out of master to another temporary location, merge the old coolNewStuff (which was same as the master at the time you branched off) with the new changes on the master and then places your changes on top of it.

    This process rewrites the history of the branch.

    If you get conflicts. resolve the conflicts and add the files back

    git add fileName
    

    Continue with rebase

    git rebase --continue
    

    Do a git log and see that your changes are on top of the latest changes of master branch.

    Now You won’t be able to push the changes to coolNewStuff branch as the history of branch has been rewritten.

    On doing git status you would get a message saying

    Your branch and ‘origin/coolNewStuff’ have diverged

    You will need to remove your remote branch

    git push origin :coolNewStuff
    

    and push again. Do remember to notify other guys who are working on the coolNewStuff branch to delete their local coolNewStuff branch and fetch the new coolNewStuff branch.

    Now when you merge this branch with master you will see that your changes are on top of the recent stuff on master and you can easily roll back the stuff in case something goes wrong.

    Hope this helps.

    Sachin Anand

    email : sachin[at]intelligrape[dot]com

    twitter : @sachin__anand

    • Share/Bookmark
  • Dbconsole in Grails.

    25 Dec 2011 in Database& Grails

    So, Grails 2.0 was released a few days back and I upgraded my application to it as soon as I came to know of its final release and it rocks.!!

    Among the many things which are making a lot of noise on grails 2.0, there seems to be a lack of noise over the GUI Database console which grails has provided. Developers can connect to the database from a GUI right inside there application, see the data in tables and execute simple queries. Probably its not polished yet so that could be a reason why there is not much noise over it but it still is a usable feature.

    All you need to do is, run your grails 2.0 app navigate to http://localhost:8080/app-name/dbconsole/ and configure your database connection. Just select what database you are using, Select the driver, a couple of entries for username and password and you are good to go.

    The query builder isn’t too great, but that is no reason to miss this useful tool. No need to move to any other application or console to see whats in the database. The database is available right in your application, and its available only in development mode, so no worries of this slipping into production. Hope this saves some time for all of us.

    Thanks.
    Sachin Anand
    mail : sachin[at]intelligrape[dot]com
    twitter : @sachin__anand

    • Share/Bookmark
  • Sorting in javascript

    13 Mar 2011 in Javascript/Ajax/JQuery

    Recently in my project I needed to sort an object list on the basis of object name. For the same purpose I created the following function

    
    function sortList(objList) {
     objList.sort(sortByName);
    }
    
    function sortByName(a, b) {
     var x = a.name;
     var y = b.name;
     return ((x < y) ? -1 : ((x > y) ? 1 : 0));
    }
    

    This function sorts an object list on the basis of name of object. Hope it helps

    Sachin Anand

    sachin[at]intelligrape[dot]com

    • Share/Bookmark
  • Getting up and Running With Cassandra

    17 Jan 2011 in Database

    Luckily, I got some time outside my usual obligations in the project, to learn something new and I devoted the time to getting up and running with cassandra . Getting starting up with it was a bit bumpy, as the case almost always is when you start with something entirely new.

    Lets get Started..

    1) First step of course is to get the binary files for the cassandra from here

    2) It is assumed that you have got jdk>1.5 installed on your machine and JAVA_HOME variable is set. Now extract the tar file to the location you want (I extracted in the /opt folder and created a soft link to it with name cassandra).

    3) Create the necessary directories for cassandra in /var/lib and /var/log folders and change their ownership

    
    sudo mkdir -p /var/lib/cassandra
    
    sudo chown -R "user" /var/lib/cassandra
    
    sudo mkdir -p /var/log/cassandra
    
    sudo chown -R "user" /var/log/cassandra
    

    Now move the extracted cassandra project move to the bin folder inside it (in my case /opt/cassandra/bin) and type the command

    
    ./cassandra  -f
    

    The -f switch will ensure that cassandra runs in the foreground and its logs will print to standard output.

    Now a few lines similar to a java stack trace will appear. I expected to see some kind of “successful or server running message” but there was none. So if you are not seeing any FATAL or ERROR messages it means you have succeeded in running cassandra. :)

    Now notice in that stack trace that your cassandra runs on port 9160 by default.

    So to connect to cassandra open a new terminal and start the cassandra CLI available in the same bin folder.

    
    ./cassandra-cli
    

    You will see a message like

    Welcome to cassandra CLI.

    Type ‘help;’ or ‘?’ for help. Type ‘quit;’ or ‘exit;’ to quit.
    [default@unknown]

    typing help here will show you a list of commands available.

    Now, we will connect to the cassandra server instance we started earlier.

    
    connect localhost/9160;
    

    Don’t miss that semicolon ;) . All statements here must end with semicolon.

    You will now be connected to a “Test Cluster”. It is the default cluster which comes with cassandra. Cluster is a container which encapsulates many ‘keyspaces’ and keyspaces are things similar to a database in relational DBMS. I better leave the data model topic here and concentrate on task at hand. I intend to take up data model topic in a separate blog.

    So, Now we have a cluster to work in.

    We will create a keyspace (database in relational DBMS world) and then enter and retrieve some data from it.

    First of all lets see what all keyspaces are already available. Invoke

    
    show keyspaces;
    

    The  keyspaces you see are used by cassandra and are not to be intended to be used by the us. So lets make our own keyspace.

    
    create keyspace CustomKeySpace with replication_factor=1;
    
    use CustomKeySpace;
    

    What we have just done is created a new keyspace and started using in. (Quite similar to create database <database-name>; and use <database-name>;) Lets leave replication_factor for now.

    [default@unknown]
    [default@unknown] use CustomKeySpace;
    Authenticated to keyspace: CustomKeySpace
    [default@CustomKeySpace]

    notice the change from [default@unknown] to [default@CustomKeySpace]. It shows you are a “default” user which earlier was not using a keyspace and is now using CustomKeySpace. Another way to look at it is default user is “logged” into CustomKeySpace.

    Next step is to create a table, just that it is called a column-family here.

    
    create column_family user;
    

    lets enter some data to this column family now.

    
    [default@CustomKeySpace] set user ['sachin'] ['lname']= 'Anand' ;
    Value inserted.
    [default@CustomKeySpace] set user ['sachin'] ['email']= 'sachin[at]intelligrape[dot]com' ;
    
    Value inserted.
    

    Now we created two columns for user ’sachin’ one is called ['lname'] and contains value ‘Anand’, other is called ‘email’ and contains value sachin[at]intelligrape[dot]com.

    To count the number of columns for a record

    
    count user ['sachin'];
    

    To retrieve the values from the database — you guessed it we will use get.

    
    [default@CustomKeySpace] get user ['sachin'];
    => (column=656d61696c, value=73616368696e40696e74656c6c6967726170652e636f6d, timestamp=1295199962515000)
    => (column=[java]666e616d65, value=4562656e, timestamp=1295199873677000)
    Returned 2 results.
    

    problem here column names and values are coming in hex code here. So, we need to add some metadata to tell what kind of values we are expecting. here we go..

    
    [default@CustomKeySpace] update column family user with column_metadata=[{column_name:lname, validation_class:UTF8Type},{column_name:email, validation_class:UTF8Type}];
    

    Again writing get user command

    
    [default@MyKeySpace] get user ['sachin'];
    => (column=656d61696c, value=sachin@intelligrape.com, timestamp=1295199962515000)
    => (column=666e616d65, value=Anand, timestamp=1295199873677000)
    Returned 2 results.
    

    So we have got the results we wanted. So in this small article we learnt how to start cassandra connect to it. create a new keyspace add a column_family and set and get data from it. I will be back with more on this for sure.

    Thanks & Regards.

    Sachin Anand

    Email  : sachin[at]intelligrape[dot]com

    • Share/Bookmark
  • MalformedByteSequenceException with grails jasper plugin 1.1.6

    03 Dec 2010 in Java tools

    Hi All,

    I was facing a lot of problems with creating pdf reports using jasper plugin 1.1.6 in grails, Though I had earlier worked with 0.9.5 and 0.9.7 versions of the plugin with a lot of ease but some how 1.1.6 version of plugin was not generating reports  it always ended up throwing MalformedByteSequenceException: Invalid byte 1 of 1-byte UTF-8 sequence.

    com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException: Invalid byte 1 of 1-byte UTF-8 sequence.
     at com.sun.org.apache.xerces.internal.impl.io.UTF8Reader.invalidByte(UTF8Reader.java:684)
     at com.sun.org.apache.xerces.internal.impl.io.UTF8Reader.read(UTF8Reader.java:554)
     at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.load(XMLEntityScanner.java:1742)
     at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.arrangeCapacity(XMLEntityScanner.java:1619)
     at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.skipString(XMLEntityScanner.java:1657)
     at com.sun.org.apache.xerces.internal.impl.XMLVersionDetector.determineDocVersion(XMLVersionDetector.java:193)
     at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:772)
     at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:737)
     at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:119)
     at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1205)
     at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:522)
     at org.apache.commons.digester.Digester.parse(Digester.java:1647)
     at net.sf.jasperreports.engine.xml.JRXmlLoader.loadXML(JRXmlLoader.java:241)
     at net.sf.jasperreports.engine.xml.JRXmlLoader.loadXML(JRXmlLoader.java:228)
     at net.sf.jasperreports.engine.xml.JRXmlLoader.load(JRXmlLoader.java:216)
     at net.sf.jasperreports.engine.JasperCompileManager.compileReport(JasperCompileManager.java:199)
     at net.sf.jasperreports.engine.JasperCompileManager$compileReport.call(Unknown Source)
     at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:149)
     at java.lang.Thread.run(Thread.java:662)

    I tried various things like changing the header of the jrxml file, adding new attributes in jasperReport tag and changing encoding type but to no Avail. Then I tried generating report without the .jasper files and deleted all jasper files except for sub-reports (sub-reports need to be in a pre-compiled state for the plugin to work)  and thing started working. For some strange reason the plugin was throwing exception when jasper report was available but if the report was compiled on the fly the plugin had no trouble with it. I am not sure what may be the reason may be I-report or something, but I got a move on. Hope You will too.

    With Regards

    Sachin Anand

    sachin[at]intelligrape[dot].com

    • Share/Bookmark
  • Only Read and Insert In Domain Class

    14 Nov 2010 in Grails

    In my recent Project, I wanted to create a domain class in which records could only be added and read and no update was to be allowed on any of the records and I found a very nice way of doing it. Adding

    static mapping = {
        cache usage: 'read-only'
        version false
      }
    

    in the domain class did the trick for me and now, in this domain only read and create is possible. No updates and deletes. :)

    With Regards
    Sachin Anand

    • Share/Bookmark
  • Working with Excel Import Plugin

    14 Oct 2010 in Grails

    In a use case, I needed to import excel spreadsheet and save the data in the database, that was when I came across grails’ excel import plugin. All I had to do was install the plugin and start using it. No Fuss. I created a class in my src/groovy folder

    import org.grails.plugins.excelimport.*
    class StudentImportXLS extends AbstractExcelImporter {
    
     static Map CONFIG_BOOK_COLUMN_MAP = [sheet:'Sheet1', startRow: 1, columnMap:[ 'A' : 'firstName','B':'lastName', 'D':'gender' , 'E' :'birthday', 'F': 'inStudentDirectory']]
    
      static Map propertyConfigurationMap = [
              firstName:([expectedType: ExcelImportUtils.PROPERTY_TYPE_STRING, defaultValue:null]),
              lastName:([expectedType: ExcelImportUtils.PROPERTY_TYPE_STRING, defaultValue:0]),
              ('birthday'):([expectedType: ExcelImportUtils.PROPERTY_TYPE_STRING, defaultValue:null])]
    
    public StudentImportXLS(fileName){
      super(fileName)
    }
    
    List<Map> getStudents(){
      List studentList = ExcelImportUtils.convertColumnMapConfigManyRows(workbook, CONFIG_BOOK_COLUMN_MAP, null, propertyConfigurationMap)
      return studentList
    }
    }
    

    In this class I am defining a Map (CONFIG_BOOK_COLUMN_MAP) which tells you which column of excel file is mapped to which field. It also maps from which row to start extracting the data and which sheet Number.

    In the second Map (propertyConfigurationMap) we are providing what type of value we are expecting and a default value for it if the value is missing.

    Now what getStudents() method does is it gives a list of maps for the whole spreadsheet and it will return the data you wanted as a list of maps.

    All You need to do now is, in your service/controller write

    StudentImportXLS importer = new StudentImportXLS(fileName)
    def studentsMapList = importer.getStudents()
    

    here fileName is the path where you have saved the file on your server, and in studentsMapList you get the list of Maps. Now iterate over the list and use the maps to create and save objects. That is about it. :) . The Plug-in provides many more features which we can use.

    There was a small problem which I faced with the date, as you would have noticed I am trying to get value as a string for the birthday field (propertyConfigurationMap) getting a date was giving me joda time date. But it was not working properly for some dates like 08/15/2010 (15th August 2010) I was getting a String value but for dates like 08/05/2010 (5th August 2010) it gave me an object of jodatime date. I found a work around for it

    // student Map is one object from list of maps.
     if (studentMap.birthday instanceof String) {
                student.birthday = new Date(studentMap.birthday)
              } else {
                String tempDate = studentMap.birthday.toString()
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-dd-MM");
                student.birthday = sdf.parse(tempDate)
              }
    

    looking at the code it is clear that I am saving the date as java.util.Date not as jodatime date.
    Other than this small issue it was great using this plugin and it saves a lot of effort.
    Hope it helps.

    With Regards
    Sachin Anand
    sachin@intelligrape.com

    • Share/Bookmark
  • Passing Optional Parameters in jasper reports

    13 Sep 2010 in Java tools

    Hi Guys,

    In one of my projects, While working with jasper reports, one of the requirement I faced was of passing optional parameter to the sql query in jasper  report. For eg. I had to write a query to find all new customers which were added between two given dates and if an optional status value of the customer is passed the report should should be further refined to include only those customer which were added and had the same status value as passed, If the status is not provided it should be ignored in SQL query in jasper report. So, in this case the status was an optional parameter.

    The solution I found was pretty elegant. On searching over the net, I found that parameters with an ! (exclamation) mark are compiled before the query is executed. That is,

    $P!{status}

    will be compiled before the query is executed. So, I passed the status from my code in to the jasper report. Now, to take care of the condition that it could be optional, I added a new parameter inside the jasper report, say “status_value”. such that, status_value had a default value expression (DFE) :

     
    ($P{status}=="" ? " and customer.status=' "+ $P{status} + " ' " )

    Now in the SQL query in jasper I wrote

    SELECT * FROM customer WHERE customer.start_date=$P{startDate} AND customer.end_date=$P{endDate} 
    $P!{status_value}

    what it does is that status_value is compiled before the execution of query. So the condition in the DFE of status_value checks whether we a receive a status from outside or not, If we do the condition will be appended in the query. Other wise it won’t be appended and we are done. :) .

    With Regards

    Sachin Anand
    sachin@intelligrape.com

    • Share/Bookmark
  • Using bindData in services

    11 Aug 2010 in Grails

    In one of my projects, I was working on rest calls, and one of the requirement was such that I had to pass the XML to service and then parse it and bind the relevant details to an instance of a domain object. In essence I had to call bindData in service after creating a Map from the XML. I soon realised we could not call bindData in service, its a method injected by grails only in controllers. After searching for stuff on google.. I found the way out, it was simple All we have to do is

    import org.codehaus.groovy.grails.web.metaclass.BindDynamicMethod

    and then in your method do

    BindDynamicMethod bind = new BindDynamicMethod()
    args =  [objectInstance, map, [exclude:['prop1', 'prop2']]]
            bind.invoke(objectInstance,'bind',(Object[]) args)

    Here is the Link which I referred JT’s Blog it will give you a little more detail regarding using bindData in services.

    Hope it helps.

    With Regards
    Sachin Anand
    sachin@intelligrape.com

    • Share/Bookmark
  • Generating stubs for SOAP calls using IntelliJ IDEA

    13 Jul 2010 in Java tools

    Since working with SOAP calls in XML is very tiresome, we have libraries like axis and wsdl2java to generate stubs to make web-service client calls. I generated the stubs using IntelliJ IDEA to make SOAP calls in grails using the steps below.

    1. Adding Framework Support

    If the IntelliJ project does not already have the framework support, then add it by right clicking on the “ProjectName” project and selecting the “Add Framework Support”. Go to Web services client in left pane and select Apache Axis in the right pane. Also, specify the path where you want necessary files to be downloaded. It will prompt you to download files. Just click “Yes”.

    2. Generate Java code from WSDL

    Right click the project’s src/java directory, and select “Webservices >> Generate Java code from WSDL”. Now point to the URL and ensure that the “output path” points to “src/java” .

    Using the generated stub, we should now be able to invoke web service calls by importing in the necessary classes where ever we want to use them.

    No more haggling with XML.. cheers…!!!

    ~~With Regards~~

    ~~Sachin Anand~~

    ~~sachin@intelligrape.com~~

    • Share/Bookmark