Java

Search a word in a two dimensional array using Java

Posted on
Overview

I was playing this word search game with my children when I realized that I can create a simple Java application that search for words in a grid.
You can checkout the source code at https://github.com/mrprintedwall/search-a-word-in-a-two-dimensional-array-using-java

Algorithm Concept
Grid Algorithm Concept
My approach starts by creating a two dimensional character array and use a loop within a loop to iterate through the rows and columns. Since we know the length of the keyword we can extract the sequence of characters from the matrix from a specified direction.
Project Structure

MainApp.java

In this example, I created a 15×15 character array and populate it with strings per row. This program uses the program argument to set the keyword.

public class MainApp {
    public static void main(String[] args) {
        char[][] m = new char[15][15];
        m[0] = "LRHCODRUMAJTMLE".toCharArray();
        m[1] = "IYDTANDARPMAKLJ".toCharArray();
        m[2] = "SNOTKKASHINGLHD".toCharArray();
        m[3] = "IARESWALTONIKAJ".toCharArray();
        m[4] = "NMTFAQLHBTSOKLM".toCharArray();
        m[5] = "TDEFPMCPYOWHGUA".toCharArray();
        m[6] = "TIGUIEIANKMUYAB".toCharArray();
        m[7] = "ARABRAGTDELWLDR".toCharArray();
        m[8] = "RFJBEMPXTENTKDA".toCharArray();
        m[9] = "NRLPDBDOHALXNAM".toCharArray();
        m[10] = "AAQRZAVUTHLSWWO".toCharArray();
        m[11] = "UFRZQNRMAAGDOBV".toCharArray();
        m[12] = "LKJKNIRBDSNNJNI".toCharArray();
        m[13] = "TCEGATESCMLIIMC".toCharArray();
        m[14] = "FEMORDASHOVANSH".toCharArray();
        MatrixReader matrixReader = new MatrixReader(m);
        ConsoleDisplay consoleDisplay = new ConsoleDisplay(m);
        try {
            if(args.length > 0)
            {
                SearchResult searchResult = matrixReader.searchWord(args[0]);
                if(searchResult != null)
                {
                    consoleDisplay.displayResult(searchResult);
                }
            }
        }
        catch(Exception exception)
        {
            System.out.println(exception.getMessage());
        }
    }
}
SearchResult.java

This class will contain the details of the found keyword. pointer1 will hold the first character position while pointer2 will hold the position the last character.

To help with console highlight, I added a pointer chains which will hold the sequence of position to highlight.

public class SearchResult {
    private Pointer pointer1;
    private Pointer pointer2;
    private String keyword;
    private Pointer[] chains;

    public SearchResult(Pointer pointer1, Pointer pointer2, String keyword, Pointer[] chains)
    {
        this.pointer1 = pointer1;
        this.pointer2 = pointer2;
        this.keyword = keyword;
        this.chains = chains;
    }

    public Pointer getPointer1()
    {
        return this.pointer1;
    }

    public Pointer getPointer2()
    {
        return this.pointer2;
    }

    public String getKeyword()
    {
        return this.keyword;
    }

    public Pointer[] getChains()
    {
        return this.chains;
    }
}
MatrixReader.java

The search algorithm starts by iterating through the cells and check if the cell contains the starting character of the keyword.
It then performs a directional string extraction base on the keyword size and execute a string comparison. If the keyword is
found it returns the result.

The method extractByDirection has a logic to not execute the extraction if the starting position and angle of extraction will intersect with the array boundary.

public class MatrixReader implements IMatrixReader {
    protected char[][] matrix;
    protected int xmin = 0;
    protected int ymin = 0;
    protected int xmax = 0;
    protected int ymax = 0;

    public MatrixReader(char[][] matrix) {
        this.matrix = matrix;
        this.xmax = this.matrix[0].length;
        this.ymax = this.matrix.length;
    }
    
    public SearchResult searchWord(String keyword) throws Exception {
        if(this.matrix != null && keyword != null) {
            
            int keySize = keyword.length();
            if(keySize == 0)
            {
                throw new Exception("Keyword is empty");
            }

            for(int y = this.ymin; y < this.ymax; ++y){
                for(int x = this.xmin; x < this.xmax; ++x)
                {
                    if(this.matrix[y][x] == keyword.charAt(0))
                    {
                        SearchResult searchResult = extractByDirection(new Pointer(x, y), keySize, Angle.A0);
                        if(searchResult != null && searchResult.getKeyword().equals(keyword)) {
                            return searchResult;
                        }

                        searchResult = extractByDirection(new Pointer(x, y), keySize, Angle.A90);
                        if(searchResult != null && searchResult.getKeyword().equals(keyword)) {
                            return searchResult;
                        }

                        searchResult = extractByDirection(new Pointer(x, y), keySize, Angle.A180);
                        if(searchResult != null && searchResult.getKeyword().equals(keyword)) {
                            return searchResult;
                        }

                        searchResult = extractByDirection(new Pointer(x, y), keySize, Angle.A270);
                        if(searchResult != null && searchResult.getKeyword().equals(keyword)) {
                            return searchResult;
                        }

                        searchResult = extractByDirection(new Pointer(x, y), keySize, Angle.A45);
                        if(searchResult != null && searchResult.getKeyword().equals(keyword)) {
                            return searchResult;
                        }

                        searchResult = extractByDirection(new Pointer(x, y), keySize, Angle.A135);
                        if(searchResult != null && searchResult.getKeyword().equals(keyword)) {
                            return searchResult;
                        }
                        
                        searchResult = extractByDirection(new Pointer(x, y), keySize, Angle.A225);
                        if(searchResult != null && searchResult.getKeyword().equals(keyword)) {
                            return searchResult;
                        }

                        searchResult = extractByDirection(new Pointer(x, y), keySize, Angle.A315);
                        if(searchResult != null && searchResult.getKeyword().equals(keyword)) {
                            return searchResult;
                        }
                    }
                }
            }
            return null;
        }
        throw new NullPointerException("Matrix is null");
    }

    public SearchResult extractByDirection(Pointer pointer, int size, int direction) {
        String sample = "";
        Pointer[] chains = new Pointer[size];
        if(direction == Angle.A0)
        {
            if((pointer.getX()+size) <= this.xmax)
            {
                for(int x = pointer.getX(), i = 0; x < (pointer.getX()+size); ++x, ++i)
                {
                    sample += matrix[pointer.getY()][x];
                    chains[i] = new Pointer(x, pointer.getY());
                }
                return new SearchResult(pointer, new Pointer(pointer.getX()+size, pointer.getY()), sample, chains);
            }
        }
        else if(direction == Angle.A90)
        {
            if((pointer.getY()-size) >= this.ymin)
            {
                for(int y = pointer.getY(), i = 0; y > (pointer.getY()-size); --y, ++i)
                {
                    sample += matrix[y][pointer.getX()];
                    chains[i] = new Pointer(pointer.getX(), y);
                }
                return new SearchResult(pointer, new Pointer(pointer.getX(), (pointer.getY()-size)), sample, chains);
            }
        }
        else if(direction == Angle.A180)
        {
            if((pointer.getX()-size) >= this.xmin)
            {
                for(int x = pointer.getX(), i = 0; x > (pointer.getX()-size); --x, ++i)
                {
                    sample += matrix[pointer.getY()][x];
                    chains[i] = new Pointer(x, pointer.getY());
                }
                return new SearchResult(pointer, new Pointer((pointer.getX()-size), pointer.getY()), sample, chains);
            }
        }
        else if(direction == Angle.A270)
        {
            if((pointer.getY()+size) <= this.ymax)
            {
                for(int y = pointer.getY(), i = 0; y < (pointer.getY()+size); ++y, ++i)
                {
                    sample += matrix[y][pointer.getX()];
                    chains[i] = new Pointer(pointer.getX(), y);
                }
                return new SearchResult(pointer, new Pointer(pointer.getX(),(pointer.getY()+size)), sample, chains);
            }
        }
        else if(direction == Angle.A45)
        {
            if(((pointer.getY()-size) >= this.ymin) && ((pointer.getX()+size <= this.xmax)))
            {
                for(int y = pointer.getY(), x = pointer.getX(), i = 0; (y > (pointer.getY()-size)) && (x < (pointer.getX()+size)); --y, ++x, ++i)
                {
                    sample += matrix[y][x];
                    chains[i] = new Pointer(x, y);
                }
                return new SearchResult(pointer, new Pointer((pointer.getX()+size),(pointer.getY()-size)), sample, chains);
            }
        }
        else if(direction == Angle.A135)
        {
            if(((pointer.getY()-size) >= this.ymin) && ((pointer.getX()-size >= this.xmin)))
            {
                for(int y = pointer.getY(), x = pointer.getX(), i = 0; (y > (pointer.getY()-size)) && (x > (pointer.getX()-size)); --y, --x, ++i)
                {
                    sample += matrix[y][x];
                    chains[i] = new Pointer(x, y);
                }
                return new SearchResult(pointer, new Pointer((pointer.getX()-size),(pointer.getY()-size)), sample, chains);
            }
        }
        else if(direction == Angle.A225)
        {
            if(((pointer.getY()+size) <= this.ymax) && ((pointer.getX()-size >= this.xmin)))
            {
                for(int y = pointer.getY(), x = pointer.getX(), i = 0; (y < (pointer.getY()+size)) && (x > (pointer.getX()-size)); ++y, --x, ++i)
                {
                    sample += matrix[y][x];
                    chains[i] = new Pointer(x, y);
                }
                return new SearchResult(pointer, new Pointer((pointer.getX()+size),(pointer.getY()+size)), sample, chains);
            }
        }
        else if(direction == Angle.A315)
        {
            if(((pointer.getY()+size) <= this.ymax) && ((pointer.getX()+size <= this.xmax)))
            {
                for(int y = pointer.getY(), x = pointer.getX(), i = 0; (y < (pointer.getY()+size)) && (x < (pointer.getX()+size)); ++y, ++x, ++i)
                {
                    sample += matrix[y][x];
                    chains[i] = new Pointer(x, y);
                }
                return new SearchResult(pointer, new Pointer((pointer.getX()+size),(pointer.getY()+size)), sample, chains);
            }
        }
        return null;
    }
}
Demo/Screenshots
Search for GATES
Search for ELLISON
Search for ALBRECHT
Conclusion

There are other algorithms and ways out there to solve this type of problem but in my situation and time constraint this is good enough.

General

Generating Subresource Integrity (SRI)

Posted on

Since launching my online recruitment platform and job vacancy portal. I became interested in rolling out my own content delivery network (CDN) to host my portal’s images, javascript and CSS. Thanks to NGINX, implementing a CDN is easy. Of course we need to ensure that our digital assets are not compromised during transport so we need to add Subresource Integrity (SRI) to our files.

openssl dgst -sha384 -binary site.css | openssl base64 -A

Using openssl is fine but I want to try writing a golang base program to generate the SRI hash for me. You can find the snippet below and code at my github https://github.com/mrprintedwall/srigen

package main

import (
	"crypto/sha512"
	b64 "encoding/base64"
	"fmt"
	"io/ioutil"
	"os"
)

func main() {
	args := os.Args[1:] // Fetch the program arguments excluding the program name
	if len(args) == 0 {
		fmt.Println("Usage: srigen \"filename\"")
	} else {
		b, err := ioutil.ReadFile(args[0])
		if err != nil {
			panic(err)
		}
		hash := sha512.New384()

		hash.Write(b)
		hashResult := hash.Sum(nil)

		result := b64.StdEncoding.EncodeToString(hashResult)
		fmt.Printf("sha384-%s\n", result)
	}
}
Subresource Integrity used in CDN
Subresource Integrity used in CDN
MySQL

Using MySQL TIMESTAMPDIFF to delete unverified user records

Posted on

Building a public website with user registration and email verification is typical. It will require users to validate their email by clicking a unique generated URL link.
Sometimes, user registration with pending verification will grow exponentially and needs an automated cleanup of records.

In this example I created a simple MySQL stored procedure to delete users with “pending-email-verification” status for more than five days.

TIMESTAMPDIFF(unit, datetime1, datetime2)

CREATE DEFINER=`dbuser`@`localhost` PROCEDURE `delete_unverified_users`()
BEGIN
	DELETE FROM user WHERE user.status='pending-email-verification' AND TIMESTAMPDIFF(DAY,user.modifiedDateTime,NOW()) > 5;
	SELECT ROW_COUNT() AS 'count';
END
Tutorials

How to stop Mailtrack from tracking you

Posted on

Mailtrack is an online service that provides email tracking capability and analytics. Using its services the sender can track when the receiver read the email, when it was viewed and where is the reader’s location. It is a great tool for marketing but I feel that this is invading privacy and I would like to share to you how to stop getting tracked by mailtrack or other similar services. Internet surveillance and tracking are now more prevalent than ever which is why we have to ensure that our privacy is upheld.

How mail tracking service like Mailtrack works?

Mailtrack uses a transparent, 1×1 pixel size external reference image inserted into the email. When the unsuspecting person opens the email, the image will be loaded from and external server which then can identify that the email has been opened and read.

Steps on how to stop Mailtrack from tracking you

Procedures for

Gmail

1. Go to Gmail settings
1. Go to Gmail settings

2. From the menu, select Settings
2. From the menu, select Settings

3. Inside Gmail settings, Go to Images section and select Ask before displaying external images
3. Ask before loading external images

Linux

How to connect to a Cisco VPN in Ubuntu 18.04 LTS

Posted on

Here’s the simple steps for you to connect to a Cisco VPN in Ubuntu 18.04 LTS.

Cisco, an American company is the leading provider and manufacturer of enterprise network devices, telecommunication hardware, networking security and networking software.
According to computer profile as of April 2018, Cisco holds a 73.9% market which makes it the undisputed leader in its industry. Without further ado here
are the steps.

1. Install vpnc and network-manager-vpnc-gnome


sudo apt install vpnc network-manager-vpnc-gnome


2. Enter your password



3. Confirm installation



4. After successfully installing the required software it is time to configure it.



5. Add a new VPN connection



6. From the VPN type options, select Cisco Compatible VPN (vpnc)



7. Enter your VPN credentials and press Add



Linux

Bash string manipulation in program arguments

Posted on

In this code snippet, I would like to run an application with a URL payload based on date and time. This
code will be executed in a specific schedule everyday and I would like to dynamically inject the date and time in
the program argument when the program executes.


./json2csv rules.json "ncp" "http://localhost:8080/api/zget?eid=get-ncp-mv-by-starttime-endtime&starttime=$(date --date='yesterday' +\%Y-\%m-\%d)+00:00:00&endtime=$(date --date='yesterday' +\%Y-\%m-\%d)+23:59:00&container=false" > $(echo "nercc_mv_$(date --date='yesterday' +\%Y-\%m-\%d).csv")

The way to do this is using the Bash String Manipulation

Inside a string, the bash will evaluate statement inside “$()” in this example:

$(date --date='yesterday' +\%Y-\%m-\%d)


"http://localhost:8080/api/zget?eid=get-ncp-mv-by-starttime-endtime&starttime=$(date --date='yesterday' +\%Y-\%m-\%d)+00:00:00&endtime=$(date --date='yesterday' +\%Y-\%m-\%d)+23:59:00&container=false"

The resulting string after bash string manipulation will be like this

http://localhost:8080/api/zget?eid=get-ncp-mv-by-starttime-endtime&starttime=2018-09-27+00:00:00&endtime=2018-09-27+23:59:00&container=false
Code Snippet

Standardizing SQLite in Spring framework Project

Posted on

My approach in standardizing SQLite in a Spring framework project

In a software development world were rapid project delivery is needed. The only way for us, developer having a sense of sanity is to build standardize code for future development. In doing so, it shortens the development time but having tested and functioning code base.

ISqliteObjectAssembler.java

This interface will serve as my IOC to have my own implementation of parsing from resultset to my specific Object

/**
 * Created by mrprintedwall on 11/02/17.
 */

public interface ISqliteObjectAssembler
{
	T assemble(ResultSet resultSet) throws SQLException;
}
ISqliteRepository.java
/**
 * Created by mrprintedwall on 11/02/17.
 */

public interface ISqliteRepository
{
	//region CONNECTION

	Connection getConnection() throws SQLException;

	//endregion

	//region ROW METHODS

	/**
	 * INSERT INTO SQLITE AND RETURNS THE GENERATED PRIMARY ID
	 * @param sql
	 * @param parameters
	 * @return
	 * @throws SQLException
	 */
	int insert(String sql, Map parameters) throws SQLException;

	/**
	 * UPDATE ROWS IN SQLITE AND RETURN AFFECTED NUMBER OF ROWS
	 * @param sql
	 * @param parameters
	 * @return
	 * @throws SQLException
	 */
	int update(String sql, Map parameters) throws SQLException;

	/**
	 * DELETE ROWS IN SQLITE AND RETURN DELETED NUMBER OF ROWS
	 * @param sql
	 * @param parameters
	 * @return
	 * @throws SQLException
	 */
	int delete(String sql, Map parameters) throws SQLException;

	/**
	 * GET SINGLE ITEM FROM RESULTSET USES INJECTED OBJECT MAPPER FOR RESULTBINDING
	 * @param sql
	 * @param sqliteObjectAssembler
	 * @param 
	 * @return
	 * @throws SQLException
	 */
	 T getSingle(String sql, ISqliteObjectAssembler sqliteObjectAssembler) throws SQLException;

	/**
	 * GET LIST OF ITEMS FROM RESULTSET USES INJECTED OBJECT MAPPER FOR RESULTBINDING
	 * @param sql
	 * @param sqliteObjectAssembler
	 * @param 
	 * @return
	 * @throws SQLException
	 */
	 List getList(String sql, ISqliteObjectAssembler sqliteObjectAssembler) throws SQLException;
	
	/**
	 * GET SINGLE ITEM USING MAP OF PARAMETERS FROM RESULTSET USES INJECTED OBJECT MAPPER FOR RESULTBINDING
	 * @param sql
	 * @param parameters
	 * @param sqliteObjectAssembler
	 * @return
	 * @throws SQLException
	 */
	 T getSingle(String sql, Map parameters, ISqliteObjectAssembler sqliteObjectAssembler) throws SQLException;

	/**
	 * GET LIST OF ITEMS USING MAP OF PARAMETERS FROM RESULTSET USES INJECTED OBJECT MAPPER FOR RESULTBINDING
	 * @param sql
	 * @param parameters
	 * @param sqliteObjectAssembler
	 * @return
	 * @throws SQLException
	 */
	 List getList(String sql, Map parameters, ISqliteObjectAssembler sqliteObjectAssembler) throws SQLException;
	//endregion

	//region TABLE METHODS

	void createTable(String sql) throws SQLException;
	void alterTable(String sql) throws SQLException;
	void dropTable(String sql) throws SQLException;

	//endregion

}
SqliteDbRepository.java
/**
 * Created by mrprintedwall on 11/02/17.
 */

@Service
public class SqliteDbRepository implements ISqliteRepository
{
	private static final Logger logger = LoggerFactory.getLogger(SqliteDbRepository.class);

	private AppConfig appConfig;

	@Autowired
	public SqliteDbRepository(AppConfig appConfig)
	{
		this.appConfig = appConfig;
	}

	@Override
	public Connection getConnection() throws SQLException
	{
		try
		{
			Class.forName("org.sqlite.JDBC");
			Connection connection = DriverManager.getConnection(appConfig.getSqliteConnectionString());
			PreparedStatement preparedStatement = connection.prepareStatement("PRAGMA foreign_keys=ON");
			preparedStatement.execute();
			return connection;
		}
		catch (ClassNotFoundException classNotFoundException)
		{
			logger.error(classNotFoundException.getMessage());
		}
		return null;
	}

	@Override
	public int insert(String sql, Map parameters) throws SQLException
	{
		try(Connection connection = getConnection())
		{
			PreparedStatement preparedStatement = connection.prepareStatement(sanitizeSqlString(sql));
			if (parameters != null)
			{
				injectParameterToPreparedStatement(parameters, preparedStatement);
			}
			preparedStatement.executeUpdate();
			return getLastInsertedId(connection);
		}
	}

	@Override
	public int update(String sql, Map parameters) throws SQLException
	{
		try (Connection connection = getConnection())
		{
			PreparedStatement preparedStatement = connection.prepareStatement(sanitizeSqlString(sql));
			if (parameters != null)
			{
				injectParameterToPreparedStatement(parameters, preparedStatement);
			}
			return preparedStatement.executeUpdate();
		}
	}

	@Override
	public int delete(String sql, Map parameters) throws SQLException
	{
		try (Connection connection = getConnection())
		{
			PreparedStatement preparedStatement = connection.prepareStatement(sanitizeSqlString(sql));
			if (parameters != null)
			{
				injectParameterToPreparedStatement(parameters, preparedStatement);
			}
			return preparedStatement.executeUpdate();
		}
	}

	@Override
	public T getSingle(String sql, ISqliteObjectAssembler sqliteObjectAssembler) throws SQLException
	{
		try (Connection connection = getConnection())
		{
			PreparedStatement preparedStatement = connection.prepareStatement(sql);
			ResultSet resultSet = preparedStatement.executeQuery();
			if (resultSet != null)
			{
				return (T) sqliteObjectAssembler.assemble(resultSet);
			}
		}
		return null;
	}

	@Override
	public List getList(String sql, ISqliteObjectAssembler sqliteObjectAssembler) throws SQLException
	{
		try (Connection connection = getConnection())
		{
			PreparedStatement preparedStatement = connection.prepareStatement(sql);
			ResultSet resultSet = preparedStatement.executeQuery();
			if (resultSet != null)
			{
				List results = new ArrayList<>();
				while (resultSet.next())
				{
					try
					{
						results.add((T) sqliteObjectAssembler.assemble(resultSet));
					}
					catch (Exception exception)
					{
						logger.error(exception.getMessage());
					}
				}
				return results;
			}
		}
		return new ArrayList<>();
	}

	@Override
	public  T getSingle(String sql, Map parameters, ISqliteObjectAssembler sqliteObjectAssembler)
			throws SQLException
	{
		try (Connection connection = getConnection())
		{
			PreparedStatement preparedStatement = connection.prepareStatement(sanitizeSqlString(sql));
			if (parameters != null)
			{
				injectParameterToPreparedStatement(parameters, preparedStatement);
			}
			ResultSet resultSet = preparedStatement.executeQuery();
			if (resultSet != null)
			{
				return (T) sqliteObjectAssembler.assemble(resultSet);
			}
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public  List getList(String sql, Map parameters,
	                           ISqliteObjectAssembler sqliteObjectAssembler) throws SQLException
	{
		try (Connection connection = getConnection())
		{
			PreparedStatement preparedStatement = connection.prepareStatement(sanitizeSqlString(sql));
			if (parameters != null)
			{
				injectParameterToPreparedStatement(parameters, preparedStatement);
			}
			ResultSet resultSet = preparedStatement.executeQuery();
			if (resultSet != null)
			{
				List results = new ArrayList<>();
				while (resultSet.next())
				{
					try
					{
						results.add((T) sqliteObjectAssembler.assemble(resultSet));
					}
					catch (Exception exception)
					{
						logger.error(exception.getMessage());
					}
				}
				return results;
			}
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		return null;
	}
	
	@Override
	public void createTable(String sql) throws SQLException
	{
		tableSqlExecutor(sql);
	}

	/*

	ALTER TABLE EXAMPLE:

	ALTER TABLE table RENAME TO temp_table;

	 */

	@Override
	public void alterTable(String sql) throws SQLException
	{
		tableSqlExecutor(sql);
	}

	@Override
	public void dropTable(String sql) throws SQLException
	{
		tableSqlExecutor(sql);
	}

	/**
	 * GENERIC TABLE CREATE/ALTER/DROP SQL EXECUTOR/HANDLER
	 *
	 * @param sql
	 * @throws SQLException
	 */
	private void tableSqlExecutor(String sql) throws SQLException
	{
		try (Connection connection = getConnection())
		{
			Statement statement = connection.createStatement();
			statement.execute(sql);
		}
	}

	/**
	 * THIS INJECTS THE HASH MAP INTO THE PREPARED STATEMENT
	 *
	 * @param parameters
	 * @param preparedStatement
	 * @throws SQLException
	 */
	private void injectParameterToPreparedStatement(Map parameters, PreparedStatement preparedStatement) throws SQLException
	{
		if (parameters != null && preparedStatement != null)
		{
			for (Map.Entry entry : parameters.entrySet())
			{
				preparedStatement.setObject((int) entry.getKey(), entry.getValue());
			}
		}
	}

	/**
	 * A LITTLE BIT OF RAINBOW, AND SUGAR STRING SANITATION
	 *
	 * @param sql
	 * @return
	 */
	private String sanitizeSqlString(String sql)
	{
		if (sql != null)
		{
			return sql.trim();
		}
		return "";
	}

	/**
	 * THIS WILL RETRIEVE THE LAST GENERATED ID IN SQLITE
	 *
	 * @param connection
	 * @return
	 * @throws SQLException
	 */
	private int getLastInsertedId(Connection connection) throws SQLException
	{
		if (connection != null)
		{
			Statement statement = connection.createStatement();
			ResultSet resultSet = statement.executeQuery("SELECT last_insert_rowid()");
			if (resultSet != null)
			{
				return resultSet.getInt(1);
			}
		}
		return 0;
	}

}