001package csheets.ext.database.core;
002
003import java.sql.Connection;
004import java.sql.DriverManager;
005import java.sql.ResultSet;
006import java.sql.ResultSetMetaData;
007import java.sql.SQLException;
008import java.sql.Statement;
009import java.util.ArrayList;
010
011/**
012 * A console-based application to test the HSQL database
013 * What this application does:
014 * 
015 * 1) it creates an hsql database in the path "res/csheets/ext/database/hsql_db"
016 * 
017 * 2) it creates a table called SAMPLE_TABLE with four entries
018 * 
019 * 3) in order to view the data entered go to http://www.hsqldb.org and download
020 * the latest stable release (mine is 2.2.9)
021 * 
022 * 4) once you have it go to terminal, move to "hsqldb-2.2.9/hsqldb/lib" and 
023 * run the following command:
024 * $ java -cp hsqldb.jar org.hsqldb.util.DatabaseManagerSwing
025 * 
026 * 5) once launched, select the following:
027 * TYPE: HSQL database engine standalone
028 * DRIVER: org.hsqldb.jdbcDriver
029 * URL: jdbc:hsqldb:file:src-resources/csheets/ext/database/embebbed_db/hsql_db
030 * USER: user
031 * PASS: pass
032 * 
033 * 6) You should be prompted with the SAMPLE_TABLE that was created when this
034 * program was run
035 * 
036 * (based in the code of Karl Meissner, at http://www.hsqldb.org/doc/guide/apb.html)
037 * @author João Carreira
038 */
039public class ConsoleHsqlTest
040{
041    /* connection to the DB that persists for the entire life of the program */
042    Connection conn;                                               
043
044    public ConsoleHsqlTest(String db_file_name_prefix) throws Exception 
045    {   
046        /* Load the HSQL Database Engine JDBC driver */ 
047        /* the hsqldb.jar should be in the class path or made part of the current jar */
048        Class.forName("org.hsqldb.jdbcDriver");
049
050        /* connects to the database.   
051         * This will load the db files and start the
052         * database if it is not alread running.
053         * db_file_name_prefix is used to open or create files that hold the state
054         * of the db. It can contain directory names relative to the
055         * current working directory */
056        conn = DriverManager.getConnection("jdbc:hsqldb:" 
057                                            + db_file_name_prefix,    // filenames
058                                            "user",                     // username
059                                            "pass");                      // password
060    }
061
062    /**
063     * safe shutdown of HSQL database
064     * @throws SQLException 
065     */
066    public void shutdown() throws SQLException 
067    {
068        Statement st = conn.createStatement();
069
070        /* db writes out to files and performs clean shuts down
071         * otherwise there will be an unclean shutdown
072         * when program ends */
073        st.execute("SHUTDOWN");
074        conn.close();    // if there are no other open connection
075    }
076
077    /**
078     * select statement
079     * @param expression
080     * @throws SQLException 
081     */
082    public synchronized void query(String expression) throws SQLException 
083    {
084        Statement st = null;
085        ResultSet rs = null;
086        
087        /* statement objects can be reused with */
088        st = conn.createStatement();         
089
090        /* repeated calls to execute but we
091         * hoose to make a new one each time
092         */
093        rs = st.executeQuery(expression);   
094
095        /* do something with the result set. */
096        dump(rs);
097        st.close();    
098        
099        /* NOTE!! if you close a statement the associated ResultSet is
100         * closed too so you should copy the contents to some other object.
101         * the result set is invalidated also  if you recycle an Statement
102         * and try to execute some other query before the result set has been
103         * completely examined.
104         */
105    }
106
107    
108    /**
109     * SQL commands CREATE, DROP, INSERT and UPDATE
110     * @param expression
111     * @throws SQLException 
112     */
113    public synchronized void update(String expression) throws SQLException 
114    {
115        Statement st = null;
116        /* statements */
117        st = conn.createStatement();    
118        /* running the query */
119        int i = st.executeUpdate(expression);    
120
121        if (i == -1) 
122        {
123            System.out.println("Database error: " + expression);
124        }
125        st.close();
126    }  
127
128    /**
129     * using cursors
130     * @param rs
131     * @throws SQLException 
132     */
133    public static void dump(ResultSet rs) throws SQLException 
134    {
135        /* the order of the rows in a cursor are implementation dependent 
136         * unless you use the SQL ORDER statement */
137        ResultSetMetaData meta   = rs.getMetaData();
138        int               colmax = meta.getColumnCount();
139        int               i;
140        Object            o = null;
141
142        /* the result set is a cursor into the data.  You can only
143         * point to one row at a time assume we are pointing to BEFORE 
144         * the first row. rs.next() points to next row and returns true
145         * or false if there is no next row, which breaks the loop
146         */
147        for (; rs.next(); ) 
148        {
149            for (i = 0; i < colmax; ++i) 
150            {
151                o = rs.getObject(i + 1);    
152                System.out.print(o.toString() + " ");
153            }
154            System.out.println(" ");
155        }
156    }
157    
158    /**
159     * saves a query in an ArrayList
160     * @param expression sql expression
161     * @return arraylist with indidivual items
162     * @throws SQLException 
163     */
164    public synchronized ArrayList queryToArray(String tableName) throws SQLException 
165    {
166        Statement st = null;
167        ResultSet rs = null;
168        ArrayList temp = new ArrayList();
169        Object obj = null;
170        
171        String expression = "SELECT * FROM " + tableName + ";";
172        
173        st = conn.createStatement();         
174        rs = st.executeQuery(expression);   
175        st.close();    
176        
177        ResultSetMetaData meta = rs.getMetaData();
178        int cols = meta.getColumnCount();
179        int rows = countRows(tableName);
180        
181        for(int i = 1; i <= cols; i++)
182        {
183            obj = meta.getColumnName(i);
184            temp.add(obj);
185            System.out.println("nome da coluna = " + obj.toString());
186        }
187        
188        
189        for(; rs.next(); )
190        {
191            for(int i = 0; i < cols; i ++)
192            {
193                obj = rs.getObject(i + 1);
194                temp.add(obj);
195//                System.out.println(obj.toString());
196            }
197        }
198        
199//        String [][]result = new String[rows][cols];
200//        
201//        for(int i = 0, k = 0; i < rows; i++)
202//        {
203//            for(int j = 0; j < cols; j++, k++)
204//            {
205//                result[i][j] = temp.get(k).toString();
206//            }
207//        }
208        
209        return temp;
210    }
211    
212    /**
213     * counts rows and columns of a give database table
214     * @param tableName table name
215     * @return 2D array with number of rows (index 0) and columns (index 1)
216     * @throws SQLException 
217     */
218    public synchronized int[] countsRowsAndCols(String tableName) throws SQLException
219    {
220        int []result = new int[2];
221        int rows, cols;
222        Statement st = null;
223        ResultSet rs = null;
224        Object obj = null;
225        String sqlExpression = "SELECT * FROM " + tableName + ";";
226       
227        st = conn.createStatement();
228        rs = st.executeQuery(sqlExpression);
229        st.close();
230        ResultSetMetaData meta = rs.getMetaData();
231        rs.next();
232        
233        obj = rs.getObject(1);
234        result[0] = countRows(tableName);
235        result[1] = meta.getColumnCount();
236        
237        return result;
238    }
239    
240
241    /**
242     * counts the rows of a given table
243     * @param tableName
244     * @return
245     * @throws SQLException 
246     */
247    public synchronized int countRows(String tableName) throws SQLException
248    {
249        Statement st = null;
250        ResultSet rs = null;
251        Object obj = null;
252        String sqlExpression = "SELECT COUNT(*) FROM " + tableName + ";";
253       
254        st = conn.createStatement();
255        rs = st.executeQuery(sqlExpression);
256        st.close();
257        
258        ResultSetMetaData meta = rs.getMetaData();
259        rs.next();
260        
261        obj = rs.getObject(1);
262        
263        /* + 1 linha para guardar dados da coluna */
264        return Integer.parseInt(obj.toString()) + 1;
265    }
266    
267    
268    public String[][] queryTo2dArray(ArrayList array, String[][] table)
269    {
270        for(int i = 0, k = 0; i < table.length; i++)
271        {
272            for(int j = 0; j < table[0].length; j++, k++)
273            {
274                table[i][j] = array.get(k).toString();
275                System.out.println(table[i][j]);
276            }
277//            System.out.println("(NEWLINE)");
278        }
279        return table;
280    }
281    
282    /**
283     * Console test application
284     * @param args 
285     */
286    public static void main(String[] args) throws SQLException 
287    {
288
289        ConsoleHsqlTest db = null;
290
291        try 
292        {
293            db = new ConsoleHsqlTest("src-resources/csheets/ext/database/embebbed_db/hsql_db");
294        } 
295        catch (Exception ex1) 
296        {
297            ex1.printStackTrace();   
298            return;                  
299        }
300//        
301////        try 
302////        {
303////            /* make an empty table by declaring the id column IDENTITY, 
304////             * the db will automatically generate unique values for new rows
305//             * this is useful for row keys 
306//             */
307//            db.update("CREATE TABLE sample_table ( id INTEGER IDENTITY, str_col "
308//                    + "VARCHAR(256), num_col INTEGER)");
309//        } 
310//        catch (SQLException ex2) 
311//        {
312//
313//           /* second time we run program should throw execption since table
314//            * already there this will have no effect on the db */
315//        }
316        
317//        try 
318//        {
319//            /* make an empty table by declaring the id column IDENTITY, 
320//             * the db will automatically generate unique values for new rows
321//             * this is useful for row keys 
322//             */
323//            db.update("CREATE TABLE TABELA2 ( id INTEGER IDENTITY, str_col "
324//                    + "VARCHAR(256), num_col INTEGER)");
325//        } 
326//        catch (SQLException ex2) 
327//        {
328//
329//           /* second time we run program should throw execption since table
330//            * already there this will have no effect on the db */
331//        }
332        
333        
334//        try 
335//        {
336//            /* adding some rows - will create duplicates if run more then once
337//             * the id column is automatically generated */
338////            db.update(
339////                "INSERT INTO sample_table(str_col,num_col) VALUES('Ford', 100)");
340////            db.update(
341////                "INSERT INTO sample_table(str_col,num_col) VALUES('Toyota', 200)");
342////            db.update(
343////                "INSERT INTO sample_table(str_col,num_col) VALUES('Honda', 300)");
344////            db.update(
345////                "INSERT INTO sample_table(str_col,num_col) VALUES('GM', 400)");
346////            db.update(
347////                "INSERT INTO sample_table(str_col,num_col) VALUES('Ferrari', 600)");
348//
349//            /* doing a query */
350////            db.query("SELECT * FROM sample_table WHERE num_col < 250");
351//            
352//            /* query about all database tables */
353////            System.out.println("***** ALL TABLES *****");
354////            db.query("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.SYSTEM_TABLES where TABLE_TYPE='TABLE'");
355//            
356//            /* saving queries to arraylist */
357//            ArrayList temp = new ArrayList();
358////            temp = db.queryToArray("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.SYSTEM_TABLES where TABLE_TYPE='TABLE'");
359////            for(int i = 0; i < temp.size(); i++)
360////            {
361////                System.out.println("TABELA nº " + (i + 1) + temp.get(i).toString());
362////            }
363//            
364//            
365//           
366//            
367////            for(int i = 0; i < temp2.size(); i++)
368////            {
369////                System.out.println(temp2.get(i).toString());
370////            }
371//            
372//            
373////            System.out.println("numero de linhas");
374////            ArrayList temp3 = new ArrayList();
375////            temp2 = db.queryToArrayList("SELECT COUNT(*) FROM sample_table");
376////            
377//           // System.out.println("Número de linhas = " + db.countRows("sample_table"));
378//            
379//            // contar linhas e colunas
380//            int rc[] = new int[2];
381//            rc = db.countsRowsAndCols("tabteste");
382//            
383//            System.out.println("linha de teste");
384//            System.out.println("rows = " + rc[0]);
385//            System.out.println("cols = " + rc[1]);
386//            
387//            // guardar dardos no arraylist
388//            ArrayList temp2 = new ArrayList();
389//            temp2 = db.queryToArray("tabteste");
390//            
391//            /* save data to array */
392//            String [][]data = new String[rc[0]][rc[1]];
393//            db.queryTo2dArray(temp2, data);
394//            
395//            
396//            /* shutting down db */
397//            db.shutdown();
398//        } 
399//        
400//        catch (SQLException ex3) 
401//        {
402//            ex3.printStackTrace();
403//        }
404       
405        
406        db.query("SELECT * FROM TITULOS");
407        
408        db.update("UPDATE TITULOS SET TITLES = 'suckers' WHERE TITLES = 'fdp'");
409        
410        db.query("SELECT * FROM TITULOS");
411        
412         /* shutting down db */
413            db.shutdown();
414        
415        
416    }
417     
418}    
419