1 23 24 package org.objectweb.jorm.mapper.rdb.lib; 25 26 import org.objectweb.jorm.api.PException; 27 import org.objectweb.jorm.api.PExceptionIO; 28 import org.objectweb.jorm.mapper.rdb.adapter.api.RdbAdapter; 29 import org.objectweb.jorm.lib.AbstractPMapcluster; 30 import org.objectweb.util.monolog.api.BasicLevel; 31 32 import java.util.ArrayList ; 33 import java.util.HashMap ; 34 import java.util.Iterator ; 35 import java.util.Map ; 36 import java.util.HashSet ; 37 import java.io.FileWriter ; 38 import java.io.IOException ; 39 import java.sql.Connection ; 40 import java.sql.SQLException ; 41 import java.sql.Statement ; 42 43 48 public class RdbPMapCluster extends AbstractPMapcluster { 49 50 51 54 private ArrayList tables; 55 56 private RdbPMappingStructuresManager manager; 57 private RdbAdapter adapter; 58 63 RdbPMapCluster(String jcname, RdbPMappingStructuresManager man) { 64 super(); 65 manager = man; 66 jcNames = new HashSet (1); 67 unresolvedDependencies.add(jcname); 68 tables = new ArrayList (1); 69 structuresActive = false; 70 if (this.manager.getPMapper() != null) { 71 adapter = ((PMapperRdb) this.manager.getPMapper()).getRdbAdapter(); 72 } 73 } 74 75 81 RdbPMapCluster(String jcname, String tname, RdbPMappingStructuresManager man) { 82 this(jcname, man); 83 tables.add(new Table(tname, this)); 84 } 85 86 87 98 void addTableColumn(String tname, String cname, String type, 99 boolean notnull, boolean ispkcol, boolean isMaster) throws PException { 100 Table curt = null; 101 Iterator it = tables.iterator(); 102 while (it.hasNext()) { 103 curt = (Table) it.next(); 104 if (curt.name.equals(tname)) { 105 break; 106 } 107 curt = null; 108 } 109 if (curt == null) { 110 curt = new Table(tname, this); 112 tables.add(curt); 113 } 114 Column c = curt.getColumn(cname); 115 if (c == null) { 116 curt.addColumn(cname, type, notnull, ispkcol, isMaster); 117 } else if (isMaster) { 118 if (c.isMaster) { 119 if (!c.type.equals(type)) { 120 if (ispkcol && !c.isPkCol) { 121 c.notNull = notnull; 122 c.isPkCol = ispkcol; 123 c.type = type; 124 } else if (!ispkcol && c.isPkCol) { 125 } else { 127 throw new PException( 128 "Incompatible column definition: existing: " + c 129 + " asked : Column (name:" + cname 130 + ", type:" + type 131 + ", notNull:" + notnull 132 + ", isMaster:" + isMaster 133 + ", isPkCol:" + ispkcol 134 + ")"); 135 } 136 } 137 } else { 138 c.isMaster = true; 139 c.notNull = notnull; 140 c.isPkCol = ispkcol; 141 c.type = type; 142 } 143 } 144 } 145 146 147 148 149 150 159 boolean containColumn(String tname, String cname, String type, 160 boolean notnull) throws PException { 161 Table curt = null; 162 Iterator it = tables.iterator(); 163 while (it.hasNext()) { 164 curt = (Table) it.next(); 165 if (curt.name.equals(tname)) { 166 break; 167 } 168 curt = null; 169 } 170 if (curt == null) { 171 return false; 173 } 174 return curt.containColumn(cname, type, notnull); 175 } 176 177 182 boolean containTable(String tname) { 183 Iterator it = tables.iterator(); 184 while (it.hasNext()) { 185 Table cur = (Table) it.next(); 186 if (cur.name.equals(tname)) 187 return true; 188 } 189 return false; 190 } 191 192 197 Table getTable(String tname) { 198 Iterator it = tables.iterator(); 199 while (it.hasNext()) { 200 Table cur = (Table) it.next(); 201 if (cur.name.equals(tname)) 202 return cur; 203 } 204 return null; 205 } 206 207 212 void merge(RdbPMapCluster cl) throws PException { 213 jcNames.addAll(cl.jcNames); 214 unresolvedDependencies.addAll(cl.getUnResolvedDependencies()); 215 unresolvedDependencies.removeAll(jcNames); 216 for (int i = 0; i < cl.tables.size(); i++) { 217 Table cur = (Table) cl.tables.get(i); 218 Table t = getTable(cur.name); 219 if (t == null) { 220 tables.add(cur); 221 } else { 222 t.merge(cur); 223 } 224 } 225 } 226 227 228 229 230 232 233 239 public void createMappingStructures(boolean force) throws PException { 240 if (structuresActive) { 241 throw new PException("Cannot change mapping structures while they are under use"); 242 } 243 if (!isDefined()) { 244 throw new PException("Cannot create hosting struture: the " + 245 "following dependencies has not been resolved: " 246 + unresolvedDependencies); 247 } 248 if ((manager instanceof RdbScriptWriter) 249 && ((RdbScriptWriter)manager).isWriteScript()) { 250 Iterator it = tables.iterator(); 252 while (it.hasNext()) { 253 Table table = (Table) it.next(); 254 table.create(null); 255 } 256 } else { 257 Object conn = manager.getConnection(); 258 try { 259 260 Iterator it = tables.iterator(); 262 while (it.hasNext()) { 263 Table table = (Table) it.next(); 264 if (table.exist(RdbConnectionWrapper.narrow2SQL(conn), adapter)) { 265 if (force) { 266 throw new PException("Cannot create table " + table.name + ": already exist"); 267 } 268 } else { 269 table.create(RdbConnectionWrapper.narrow2SQL(conn)); 270 } 271 } 272 273 274 } finally { 275 manager.closeConnection(conn); 276 } 277 } 278 } 279 280 286 public void deleteData() throws PException { 287 if (!isDefined()) { 288 throw new PException("Cannot remove data: the " + 289 "following dependencies has not been resolved: " 290 + unresolvedDependencies); 291 } 292 if ((manager instanceof RdbScriptWriter) 293 && ((RdbScriptWriter)manager).isWriteScript()) { 294 Iterator it = tables.iterator(); 296 while (it.hasNext()) { 297 Table table = (Table) it.next(); 298 table.deleteData(null); 299 } 300 } else { 301 Object conn = manager.getConnection(); 302 try { 303 Iterator it = tables.iterator(); 304 while (it.hasNext()) { 305 Table table = (Table) it.next(); 306 if (table.exist(RdbConnectionWrapper.narrow2SQL(conn), adapter)) { 307 table.deleteData(RdbConnectionWrapper.narrow2SQL(conn)); 308 } else { 309 manager.logger.log(BasicLevel.WARN, 310 "Impossible to delete the data of the table '" 311 + table.name + "': table does not exist."); 312 } 313 } 314 } finally { 315 manager.closeConnection(conn); 316 } 317 } 318 } 319 320 327 public void deleteMappingStructures() throws PException { 328 if (structuresActive) { 329 throw new PException("Cannot change mapping structures while they are under use"); 330 } 331 if (!isDefined()) { 332 throw new PException("Cannot delete hosting struture: the " + 333 "following dependencies has not been resolved: " 334 + unresolvedDependencies); 335 } 336 if ((manager instanceof RdbScriptWriter) 337 && ((RdbScriptWriter)manager).isWriteScript()) { 338 Iterator it = tables.iterator(); 340 while (it.hasNext()) { 341 Table table = (Table) it.next(); 342 table.delete(null); 343 } 344 } else { 345 Object conn = manager.getConnection(); 346 try { 347 Iterator it = tables.iterator(); 349 while (it.hasNext()) { 350 Table table = (Table) it.next(); 351 if (table.exist(RdbConnectionWrapper.narrow2SQL(conn), adapter)) { 352 table.delete(RdbConnectionWrapper.narrow2SQL(conn)); 353 } 354 } 355 } finally { 356 manager.closeConnection(conn); 357 } 358 } 359 } 360 361 public RdbPMappingStructuresManager getManager() { 362 return manager; 363 } 364 } 365 366 367 370 class Table { 371 String name; 372 ArrayList columns; 373 RdbPMapCluster cluster; 374 375 376 Table(String tname, RdbPMapCluster cluster) { 377 name = tname; 378 this.cluster = cluster; 379 columns = new ArrayList (); 380 } 381 382 void addColumn(String cname, String type, boolean notnull, boolean ispkcol, boolean ismaster) 383 throws PException { 384 Column cur; 385 cur = new Column(); 386 cur.name = cname; 387 cur.type = type; 388 cur.notNull = notnull; 389 cur.isPkCol = ispkcol; 390 cur.isMaster = ismaster; 391 columns.add(cur); 392 } 393 394 void merge(Table t) throws PException { 395 for (int i = 0; i < t.columns.size(); i++) { 396 Column cur = (Column) t.columns.get(i); 397 Column c = getColumn(cur.name); 398 if (c == null) { 399 columns.add(cur); 400 } else { 401 c.merge(cur); 402 } 403 } 404 } 405 406 boolean containColumn(String cname, String type, 407 boolean notnull) throws PException { 408 Column cur; 409 Iterator it = columns.iterator(); 410 while (it.hasNext()) { 411 cur = (Column) it.next(); 412 if (cur.name.equals(cname)) { 413 return true; 414 } 415 } 416 return false; 417 } 418 419 Column getColumn(String cname) { 420 Column cur; 421 Iterator it = columns.iterator(); 422 while (it.hasNext()) { 423 cur = (Column) it.next(); 424 if (cur.name.equals(cname)) { 425 return cur; 426 } 427 } 428 return null; 429 } 430 431 void create(Connection connection) throws PException { 432 Statement stmt = null; 433 StringBuffer sb = new StringBuffer ("CREATE TABLE " + name + " ("); 434 try { 435 String sep = ""; 436 Iterator it = columns.iterator(); 437 while (it.hasNext()) { 438 sb.append(sep); 439 sep = ", "; 440 Column col = (Column) it.next(); 441 sb.append(col.name); 442 sb.append(" "); 443 sb.append(col.type); 444 if (col.notNull && col.type.indexOf("NOT NULL") == -1) { 445 sb.append(" NOT NULL"); 446 } 447 } 448 sep = ""; 449 it = columns.iterator(); 450 while (it.hasNext()) { 451 Column col = (Column) it.next(); 452 if (!col.isPkCol) { 453 continue; 454 } 455 if (sep.equals("")) { 456 sb.append(", PRIMARY KEY ("); 457 } 458 sb.append(sep); 459 sep = ", "; 460 sb.append(col.name); 461 } 462 if (!sep.equals("")) { 463 sb.append(")"); 464 } 465 sb.append(")"); 466 467 if(cluster.getManager() instanceof RdbScriptWriter && ((RdbScriptWriter)cluster.getManager()).isWriteScript()) { 470 FileWriter writer = new FileWriter (((RdbScriptWriter)cluster.getManager()).getFileName(), true); 471 writer.write(sb.toString() + ";\n"); 472 writer.close(); 473 } else { 474 stmt = connection.createStatement(); 475 stmt.execute(sb.toString()); 476 } 477 } catch (SQLException se) { 478 throw new PExceptionIO(se, "Impossible to create the table '" 479 + name + "' of the cluster " + cluster.getClusterClasses() 480 + " : " + sb.toString()); 481 } catch(IOException ioe) { 482 throw new PExceptionIO(ioe, "Problem while writting create statement in the sql script file"); 483 } finally { 484 if (stmt != null) { 485 try { 486 stmt.close(); 487 } catch (SQLException e) { 488 } 489 } 490 } 491 } 492 493 void deleteData(Connection connection) throws PException { 494 Statement stmt = null; 495 PException resex = null; 496 try { 497 StringBuffer sb = new StringBuffer ("DELETE FROM " + name); 498 if(cluster.getManager() instanceof RdbScriptWriter && ((RdbScriptWriter)cluster.getManager()).isWriteScript()) { 501 FileWriter writer = new FileWriter (((RdbScriptWriter)cluster.getManager()).getFileName(), true); 502 writer.write(sb.toString() + ";\n"); 503 writer.close(); 504 } else { 505 stmt = connection.createStatement(); 506 stmt.execute(sb.toString()); 507 } 508 } catch (SQLException se) { 509 resex = new PExceptionIO(se, "SQL problem while deleting data: class <" + name + ">"); 510 } catch(IOException ioe) { 511 throw new PExceptionIO(ioe, "Problem while writting delete statement in the sql script file"); 512 } finally { 513 if (stmt != null) { 514 try { 515 stmt.close(); 516 } catch (SQLException e) { 517 if (resex == null) { 518 resex = new PException(e, "Problem while closing statment."); 519 } 520 } 521 } 522 if (resex != null) { 523 throw resex; 524 } 525 } 526 } 527 528 void delete(Connection connection) throws PException { 529 Statement stmt = null; 530 PException resex = null; 531 try { 532 StringBuffer sb = new StringBuffer ("DROP TABLE " + name); 533 if(cluster.getManager() instanceof RdbScriptWriter && ((RdbScriptWriter)cluster.getManager()).isWriteScript()) { 536 FileWriter writer = new FileWriter (((RdbScriptWriter)cluster.getManager()).getFileName(), true); 537 writer.write(sb.toString() + ";\n"); 538 writer.close(); 539 } else { 540 stmt = connection.createStatement(); 541 stmt.execute(sb.toString()); 542 } 543 } catch (java.sql.SQLException se) { 544 resex = new PExceptionIO(se); 545 } catch(IOException ioe) { 546 throw new PExceptionIO(ioe, "Problem while writting drop table statement in the sql script file"); 547 } finally { 548 if (stmt != null) { 549 try { 550 stmt.close(); 551 } catch (SQLException e) { 552 if (resex == null) { 553 resex = new PException(e, "Problem while closing statment."); 554 } 555 } 556 } 557 if (resex != null) { 558 throw resex; 559 } 560 } 561 } 562 563 boolean exist(Connection connection, RdbAdapter adapter) throws PException { 564 try { 565 return adapter.existTable(connection, name); 566 } catch (SQLException e) { 567 throw new PException(e, "Pb while testing the existence of table " + name); 568 } 569 } 570 } 571 572 575 class Column { 576 String name; 577 String type; 578 boolean notNull; 579 boolean isPkCol; 580 boolean isMaster; 581 582 void merge(Column c) throws PException { 583 if (type != c.type) { 584 throw new PException("Impossible to merge the column " + name 585 + ": column type does not match"); 586 } 587 if (c.isMaster) { 588 notNull = c.notNull; 589 isPkCol |= c.isPkCol; 590 } 591 } 592 593 public String toString() { 594 return "Column (name:" + name 595 + ", type:" + type 596 + ", notNull:" + notNull 597 + ", isMaster:" + isMaster 598 + ", isPkCol:" + isPkCol 599 + ")"; 600 } 601 } 602 | Popular Tags |