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