Wednesday, October 14, 2015

HQL Use MySQL Functions By Implementing Custom Dialect

Datasource.groovy File


hibernate {
    cache.use_second_level_cache = true
    cache.use_query_cache = true
    cache.region.factory_class = 'net.sf.ehcache.hibernate.EhCacheRegionFactory'
    cache.provider_class = 'net.sf.ehcache.hibernate.EhCacheProvider'
    format_sql = false
    use_sql_comments = false
}
grails.cache.config = {
    cache {
        name 'org.hibernate.cache.UpdateTimestampsCache'
        eternal true
        maxEntriesLocalHeap 500
        persistence {
            strategy localTempSwap
        }
    }
}

/* environment specific settings */
environments {
    development {
        dataSource {
            pooled = true
            url = "jdbc:mysql://localhost/db_name?useUnicode=yes&characterEncoding=UTF-8"
            driverClassName = "com.mysql.jdbc.Driver"
            username = "root"
            password = ""
            dialect = "com.pkm.custom.CustomMySQLDialect"
            dbCreate = "update"
            properties {
                maxActive = 1000
                maxIdle = 100
                minIdle = 50
                initialSize = 1
                minEvictableIdleTimeMillis = 60000
                timeBetweenEvictionRunsMillis = 60000
                numTestsPerEvictionRun = 3
                maxWait = 10000
                testOnBorrow = true
                testWhileIdle = true
                testOnReturn = true
                validationQuery = "SELECT 1"
                minEvictableIdleTimeMillis = 1800000
                timeBetweenEvictionRunsMillis = 1800000
            }
            logSql = false
            loggingSql = false
        }
    }
    test {
        dataSource {
            
        }
    }
    production {
        dataSource {
            
        }
    }
}
log4j = {
    debug 'org.hibernate.SQL'
    trace 'org.hibernate.type.descriptor.sql.BasicBinder'
}

Custom Dialect (.groovy) Used In Datasource

import org.hibernate.dialect.MySQL5InnoDBDialect
import org.hibernate.dialect.function.SQLFunctionTemplate
import org.hibernate.dialect.function.StandardSQLFunction
import org.hibernate.type.IntegerType
import org.hibernate.type.StringType
import org.hibernate.type.TimestampType

class CustomMySQLDialect extends MySQL5InnoDBDialect {
    public CustomMySQLDialect() {
        super()

        /* convert_tz('2015-01-01', '+00:00', '+10:00') = '2015-01-01 10:00' */
        /* convert_tz('2015-01-01 00:00', '+00:00', '+10:00') = '2015-01-01 10:00' */
        /* convert_tz('2015-01-01 20:00', '+00:00', '-10:00') = '2015-01-01 10:00' */
        registerFunction("convert_tz", new StandardSQLFunction("convert_tz"))

        /* group_concat(name) = 'a,b,c,c,d' */
        registerFunction("group_concat", new StandardSQLFunction("group_concat", new StringType()))

        /* group_concat_unique(name) = 'a,b,c,d' */
        registerFunction("group_concat_unique", new SQLFunctionTemplate(new StringType(), "group_concat(DISTINCT ?1)"))

        /* date_add_interval('2015-01-01', DAY, 10) = '2015-01-11' */
        /* date_add_interval('2015-01-20', DAY, -10) = '2015-01-10' */
        registerFunction("date_add_interval", new SQLFunctionTemplate(TimestampType.INSTANCE, "date_add(?1, INTERVAL ?3 ?2)"))

        /* index_of('am', 'i am good') = 3 */
        /* index_of('asm', 'i am good') = 0 */
        registerFunction("index_of", new SQLFunctionTemplate(new IntegerType(), "LOCATE(?1, ?2)"))

        /* format(number, decimal_place, locale) = format(200.343, 2, 'en_AU') = '200.34' */
        registerFunction("format", new StandardSQLFunction("format", new StringType()))
    }

    @Override
    public String transformSelectString(String select) {
        select = super.transformSelectString(select);
        return select;
    }
}

Wednesday, September 30, 2015

Myob Cloud Integration: Use Filter In Myob Integration


Equal Method (String)
{domain}/{cf guid}/Sale/Invoice/?$filter=PaymentDetails/Method eq 'Cash'

Equal Method (UID)
{domain}/{cf guid}/Sale/Invoice/?$filter=Customer/UID eq guid'd61a6a86-453a-48bf-9402-6eb6b4ea23cf'

Equal Method (Boolean)
{domain}/{cf guid}/Contact/?$filter=IsIndividual eq true

Filtering in List
{domain}/{cf guid}/Contact/Customer/?$filter=Addresses/any(x: x/Email eq null) 

Equal Method (Date)
{domain}/{cf guid}/Purchase/Bill/?$filter=Date ge datetime'2014-07-01' and Date le datetime'2014-09-24'

Sunday, August 30, 2015

Grails Get/Use Http Session In Service Or Util Class

import org.codehaus.groovy.grails.web.util.WebUtils
import javax.servlet.http.HttpSession

HttpSession httpSession = WebUtils.retrieveGrailsWebRequest().request.session

Sunday, August 2, 2015

Grails :: How To Override g Message Tag

1. Create a tab lib (grails-app/taglib)

2. Extend with ValidationTagLib

3. Example

package com.test.taglib

import org.codehaus.groovy.grails.plugins.web.taglib.ValidationTagLib

class MyCustomTagLib extends ValidationTagLib {
 static validationTagLibStatic = null

    static namespace = "g"

    Closure message = { attrs ->
        ValidationTagLib validationTagLib = validationTagLibStatic ?: (validationTagLibStatic = grailsAttributes.applicationContext.getBean('org.codehaus.groovy.grails.plugins.web.taglib.ValidationTagLib'))
        validationTagLib.message.call(attrs)
    }
}

Friday, July 31, 2015

Grails Add New Resources To MessageSource Dynamically


First create a groovy file with the following contents

package com.pkm.message.test

import grails.util.Environment
import javax.servlet.ServletContext

class MessageSourceCreator {
    public static def grailsApplication = null
    public static def servletContext = null
    public static def messageSource = null
    private static final String MESSAGE_FILE_DIR = "/WEB-INF/resources/messages"

    /**
     * @param fileName "some.message.properties"
     */
    public static void addNewMessageFile(String fileName) {
        String basePath = servletContext.getRealPath("/")
        fileName = fileName.substring(0, fileName.lastIndexOf("."))
        String relativeFilePath = "${MESSAGE_FILE_DIR}/${fileName}"

        if (Environment.isWarDeployed()) {
            messageSource.pluginBaseNames.add(0, relativeFilePath)
        } 
        else {
            String separator = Environment.current == Environment.TEST ? "/" : ""
            messageSource.pluginBaseNames.add(0, basePath + separator + relativeFilePath)
        }
    }

    public static void initialize(def ga, def sc, def ms) {
        grailsApplication = ga
        servletContext = sc
        messageSource = ms
    }
}



From BootStrap, need to call first initialize & then addNewMessageFile


/**
 * From BootStrap, need to call first initialize & then addNewMessageFile
 */
import com.pkm.message.test.MessageSourceCreator

class BootStrap {
    def grailsApplication
    def servletContext
    def messageSource

    def init = { servletContext ->
        MessageSourceCreator.initialize(grailsApplication, servletContext, messageSource)
        MessageSourceCreator.addNewMessageFile("some.message.properties")
    }

    def destroy = {

    }
}

Friday, June 26, 2015

Thursday, June 4, 2015

Android: Update GUI field vlaue/display or show a message (toast) from Thread

Util Class


package com.pkm.android.utils.thread;

import android.app.Activity;
import android.content.Context;
import android.widget.Toast;

public class ThreadUtils {
    public static Object context = null;
    private static Activity activity;
 
    /**
     * setCurrentActivity(this) in onStart()  on each activity 
     * setCurrentActivity(this) in onResume()  on each activity
     * setCurrentActivity(null) in onPause()  on each activity 
     */
    public static void setCurrentActivity(Activity currentActivity) {
        activity = currentActivity;
    }

    public static Activity currentActivity() {
        return activity;
    }
 
    public static void message(final String message) {
        activity.runOnUiThread(new Runnable() {
            public void run() {
             Toast.makeText((Context) context, message, Toast.LENGTH_SHORT).show();
            }
        });
    }
}

Example Usage


@Override
protected void onStart() {
    super.onStart();
    ThreadUtils.setCurrentActivity(this);
    ThreadUtils.context = getBaseContext();
}

ThreadUtils.message("A message from thread, will normally fail!!!");