001package csheets.ext.database.core;
002
003import java.sql.*;
004import java.util.ArrayList;
005import java.util.logging.*;
006
007import javax.swing.JOptionPane;
008
009import csheets.core.Cell;
010
011/**
012 * Creates a new connection to a derby database
013 * 
014 * @author Andre
015 * 
016 */
017public class DerbyConnection implements DBConnectionStrategy {
018
019        /** driver path */
020        private final String driverPath = "org.apache.derby.jdbc.EmbeddedDriver";
021        /** connection method */
022        private Connection connection;
023
024        @Override
025        public void createConnection(String url, String user, String pass)
026                        throws ClassNotFoundException, SQLException {
027                try {
028                        Class.forName(driverPath);
029                        connection = DriverManager.getConnection(url + ";create=true",
030                                        user, pass);
031                } catch (ClassNotFoundException e) {
032                        JOptionPane.showMessageDialog(null, "Error: class not found!");
033                } catch (SQLException e) {
034                        JOptionPane.showMessageDialog(null,
035                                        "Error: connection to database!");
036                        e.printStackTrace();
037                }
038        }
039
040        @Override
041        public void createTable(String tableName, Cell[][] cells) {
042                /* defining row and column number */
043                int numberOfColumns = cells[0].length;
044                int numberOfRows = cells.length;
045
046                /* beginning the construction of the sql statement */
047                String stat = "CREATE TABLE " + tableName + "(linha INTEGER, ";
048
049                /* the first line of the exported cells is the name of each column */
050                String[] columnsName = new String[cells[0].length];
051                String[] columnsNameCopy = new String[cells[0].length];
052
053                /* cycle to build the columns name string */
054                for (int i = 0; i < cells[0].length; i++) {
055                        /* if it's not the last column */
056                        if (i != ((cells[0].length) - 1)) {
057                                columnsName[i] = cells[0][i].getContent() + " VARCHAR(200), ";
058                                columnsNameCopy[i] = cells[0][i].getContent();
059                        }
060                        /* if it's the last column must close with bracket */
061                        else {
062                                columnsName[i] = cells[0][i].getContent() + " VARCHAR(200))";
063                                columnsNameCopy[i] = cells[0][i].getContent();
064                        }
065                }
066
067                /*
068                 * in the end of this cycle we should have the final sql statement for
069                 * table creation
070                 */
071                for (int i = 0; i < columnsName.length; i++) {
072                        stat += columnsName[i];
073                }
074
075                /* sql statement */
076                Statement st = null;
077
078                /* creates the table based on the sql statement */
079                try {
080                        st = connection.createStatement();
081                        int i = st.executeUpdate(stat);
082                        /* keep this until observer is implemented */
083                        JOptionPane.showMessageDialog(null, "Data succesfully exported!");
084                } catch (SQLException ex) {
085                        Logger.getLogger(HsqlDBConnection.class.getName()).log(
086                                        Level.SEVERE, null, ex);
087                        /* keep this until observer is implemented */
088                        JOptionPane.showMessageDialog(null, "Error: table already exists");
089                }
090
091                /* now beggins the "insert into" sql statement */
092                String insertStat = "insert into " + tableName + "(linha,";
093                for (int i = 0; i < columnsNameCopy.length; i++) {
094                        if (i != (columnsNameCopy.length - 1)) {
095                                insertStat += columnsNameCopy[i] + ",";
096                        } else {
097                                insertStat += columnsNameCopy[i] + ")";
098                        }
099                }
100                /* continuing concatenation */
101                insertStat += " VALUES(";
102
103                /* creating a number of insert statements equal to number of rows -1 */
104                String[] insertVector = new String[numberOfRows - 1];
105                for (int i = 0; i < insertVector.length; i++) {
106                        String temp = Integer
107                                        .toString(cells[i][0].getAddress().getRow() + 1);
108                        insertVector[i] = insertStat + temp + ",";
109                }
110
111                /* concatenating the respecting insert statements */
112                for (int i = 1; i < numberOfRows; i++) {
113                        for (int j = 0; j < numberOfColumns; j++) {
114                                if (j != (numberOfColumns - 1)) {
115                                        insertVector[i - 1] += "'" + cells[i][j].getContent()
116                                                        + "',";
117                                } else {
118                                        insertVector[i - 1] += "'" + cells[i][j].getContent()
119                                                        + "')";
120                                }
121                        }
122                }
123
124                /* inserting values into the table */
125                for (int i = 0; i < insertVector.length; i++) {
126                        Statement insertSt = null;
127                        try {
128                                insertSt = connection.createStatement();
129                                int j = st.executeUpdate(insertVector[i].toString());
130                        } catch (SQLException ex) {
131                                Logger.getLogger(HsqlDBConnection.class.getName()).log(
132                                                Level.SEVERE, null, ex);
133                                /* keep this until observer is implemented */
134                                JOptionPane.showMessageDialog(null, "Error: data not inserted");
135                        }
136                }
137        }
138
139        @Override
140        public void disconnet() {
141                try {
142                        connection.close();
143                } catch (SQLException ex) {
144                        Logger.getLogger(HsqlDBConnection.class.getName()).log(
145                                        Level.SEVERE, null, ex);
146                }
147        }
148
149        @Override
150        public ArrayList queryToArray() {
151                ArrayList temp = new ArrayList();
152                try {
153                        Statement st = null;
154                        st = connection.createStatement();
155                        ResultSet results = st
156                                        .executeQuery("SELECT TABLENAME FROM SYS.SYSTABLES WHERE TABLETYPE='T'");
157                        ResultSetMetaData rsmd = results.getMetaData();
158                        int numberCols = rsmd.getColumnCount();
159                        Object obj = null;
160                        for (; results.next();) {
161                                for (int i = 0; i < numberCols; i++) {
162                                        obj = results.getObject(i + 1);
163                                        temp.add(obj);
164                                }
165                        }
166                        results.close();
167                        st.close();
168                } catch (SQLException sqlExcept) {
169                        sqlExcept.printStackTrace();
170                }
171                return temp;
172        }
173
174        @Override
175        public String[] getTableList(ArrayList list) {
176                int size = list.size();
177                String[] temp = new String[size];
178                for (int i = 0; i < size; i++) {
179                        temp[i] = list.get(i).toString();
180                }
181                return temp;
182        }
183
184        @Override
185        public String[][] getTableContent(String tableName) {
186                ArrayList temp = new ArrayList();
187                int[] rowsAndCols = new int[2];
188
189                try {
190                        temp = queryToArray(tableName);
191                        rowsAndCols = countsRowsAndCols(tableName);
192                } catch (SQLException ex) {
193                        Logger.getLogger(HsqlDBConnection.class.getName()).log(
194                                        Level.SEVERE, null, ex);
195                }
196
197                return queryTo2dArray(temp, new String[rowsAndCols[0]][rowsAndCols[1]]);
198        }
199
200        @Override
201        public void updateTable() {
202                // TODO Auto-generated method stub
203                throw new UnsupportedOperationException("Not supported yet.");
204        }
205
206        @Override
207        public ArrayList queryToArray(String tableName) throws SQLException {
208                Statement st = null;
209                ResultSet rs = null;
210                ArrayList temp = new ArrayList();
211                Object obj = null;
212
213                String expression = "SELECT * FROM " + tableName;
214
215                st = connection.createStatement();
216                rs = st.executeQuery(expression);
217
218                ResultSetMetaData meta = rs.getMetaData();
219                int cols = meta.getColumnCount();
220                int rows = countRows(tableName);
221
222                for (int i = 1; i <= cols; i++) {
223                        obj = meta.getColumnName(i);
224                        temp.add(obj);
225                }
226
227                for (; rs.next();) {
228                        for (int i = 0; i < cols; i++) {
229                                obj = rs.getObject(i + 1);
230                                temp.add(obj);
231                        }
232                }
233                st.close();
234                return temp;
235        }
236
237        @Override
238        public int[] countsRowsAndCols(String tableName) throws SQLException {
239                int[] result = new int[2];
240                int rows, cols;
241                Statement st = null;
242                ResultSet rs = null;
243                Object obj = null;
244                String sqlExpression = "SELECT * FROM " + tableName;
245
246                st = connection.createStatement();
247                rs = st.executeQuery(sqlExpression);
248                ResultSetMetaData meta = rs.getMetaData();
249                rs.next();
250
251                obj = rs.getObject(1);
252                result[0] = countRows(tableName);
253                result[1] = meta.getColumnCount();
254
255                st.close();
256
257                return result;
258        }
259
260        @Override
261        public int countRows(String tableName) throws SQLException {
262                Statement st = null;
263                ResultSet rs = null;
264                Object obj = null;
265                String sqlExpression = "SELECT COUNT(*) FROM " + tableName;
266
267                st = connection.createStatement();
268                rs = st.executeQuery(sqlExpression);
269
270                ResultSetMetaData meta = rs.getMetaData();
271                rs.next();
272
273                obj = rs.getObject(1);
274
275                st.close();
276
277                return Integer.parseInt(obj.toString()) + 1;
278        }
279
280        @Override
281        public String[][] queryTo2dArray(ArrayList array, String[][] table) {
282                for (int i = 0, k = 0; i < table.length; i++) {
283                        for (int j = 0; j < table[0].length; j++, k++) {
284                                table[i][j] = array.get(k).toString();
285                        }
286                }
287                return table;
288        }
289
290        @Override
291        public void updateRow(String tableName, String column, String origin,
292                        String destination) {
293                Statement st = null;
294                String stat = "UPDATE " + tableName + " SET " + column + " = '"
295                                + origin + "' WHERE LINHA = " + Integer.parseInt(destination);
296                //System.out.println("DERBY --> " + stat);
297                try {
298                        st = connection.createStatement();
299                        int i = st.executeUpdate(stat);
300                } catch (SQLException ex) {
301                        Logger.getLogger(HsqlDBConnection.class.getName()).log(
302                                        Level.SEVERE, null, ex);
303                        /* keep this until observer is implemented */
304                        JOptionPane.showMessageDialog(null,
305                                        "Derby database error:\nCould not update!");
306                }
307
308        }
309
310    @Override
311    public void insertNewData(String tableName, String[][] newData) 
312    {
313        /* array with all insert statements */
314        String []statementVec = new String[newData.length];
315        String beginStatement = "INSERT INTO " + tableName + " VALUES ("; 
316        
317        /* begining to concatenate insert vector */
318        for(int i = 0; i < statementVec.length; i++)
319        {
320            statementVec[i] = beginStatement;
321        }
322        
323        /* adding the remaining values to insert vector */
324        for(int i = 0; i < statementVec.length; i++)
325        {
326             for(int j = 0; j < newData[0].length; j++)
327             {
328                 /* if it's the first colum is an INTEGER therefore we can't add ' at the end */
329                 if(j == 0)
330                 {
331                     statementVec[i] += newData[i][j] + ",'";
332                 }
333                 /* if it's not the first or the last is a VARCHAR and must include , for the next */
334                 if(j > 0 && j < (newData[0].length - 1))
335                 {
336                     statementVec[i] += newData[i][j] + "','";
337                 }
338                 /* if it's the last we must end the insert statement with )*/
339                 else if(j == (newData[0].length - 1))
340                 {
341                     statementVec[i] += newData[i][j] + "')";
342                 }
343             }
344        }
345        
346        /* cycle to go through all the insert statements */
347        for (int i = 0; i < statementVec.length; i++) 
348        {
349            Statement st = null;
350            try 
351            {
352                st = connection.createStatement();
353                int j = st.executeUpdate(statementVec[i].toString());
354            } 
355            catch (SQLException ex) 
356            {
357                Logger.getLogger(HsqlDBConnection.class.getName()).log(Level.SEVERE, null, ex);
358                /* keep this until observer is implemented */
359                JOptionPane.showMessageDialog(null, "Error: data not inserted");
360            }
361        }
362        /* keep this until observer is implemented */
363        //JOptionPane.showMessageDialog(null, "Derby Database: data successfully updated!");
364        
365    }
366
367    @Override
368    public void deleteRows(String tableName, String[] toDelete) 
369    {
370        String stat = "DELETE FROM " + tableName + " WHERE LINHA = ";
371        String []deleteStat = new String[toDelete.length];
372        
373        for(int i = 0; i < deleteStat.length; i++)
374        {
375            deleteStat[i] = stat + toDelete[i];
376        }
377        
378        for (int i = 0; i < deleteStat.length; i++) 
379        {
380            Statement st = null;
381            try 
382            {
383                st = connection.createStatement();
384                int j = st.executeUpdate(deleteStat[i]);
385            } 
386            catch (SQLException ex) 
387            {
388                Logger.getLogger(HsqlDBConnection.class.getName()).log(Level.SEVERE, null, ex);
389                /* keep this until observer is implemented */
390                JOptionPane.showMessageDialog(null, "Error: data not inserted");
391            }
392        }
393        
394    }
395
396}