1 28 29 package com.caucho.amber.table; 30 31 import com.caucho.amber.entity.AmberCompletion; 32 import com.caucho.amber.entity.Entity; 33 import com.caucho.amber.manager.AmberConnection; 34 import com.caucho.amber.type.EntityType; 35 import com.caucho.util.CharBuffer; 36 import com.caucho.util.L10N; 37 import com.caucho.util.Log; 38 39 import java.sql.PreparedStatement ; 40 import java.sql.ResultSet ; 41 import java.sql.SQLException ; 42 import java.util.ArrayList ; 43 import java.util.logging.Logger ; 44 45 48 public class LinkColumns { 49 private static final L10N L = new L10N(LinkColumns.class); 50 private static final Logger log = Log.open(LinkColumns.class); 51 52 private static final int NO_CASCADE_DELETE = 0; 53 private static final int SOURCE_CASCADE_DELETE = 1; 54 private static final int TARGET_CASCADE_DELETE = 2; 55 56 private Table _sourceTable; 57 private Table _targetTable; 58 59 private ArrayList <ForeignColumn> _columns; 60 61 private int _cascadeDelete; 62 63 private AmberCompletion _tableDeleteCompletion; 64 private AmberCompletion _tableUpdateCompletion; 65 66 69 public LinkColumns(Table sourceTable, Table targetTable, 70 ArrayList <ForeignColumn> columns) 71 { 72 _sourceTable = sourceTable; 73 _targetTable = targetTable; 74 75 _columns = columns; 76 77 _tableDeleteCompletion = sourceTable.getDeleteCompletion(); 78 _tableUpdateCompletion = sourceTable.getUpdateCompletion(); 79 80 _sourceTable.addOutgoingLink(this); 81 _targetTable.addIncomingLink(this); 82 } 83 84 88 public void setSourceCascadeDelete(boolean isCascadeDelete) 89 { 90 if (isCascadeDelete) { 91 assert(_cascadeDelete != TARGET_CASCADE_DELETE); 92 93 _cascadeDelete = SOURCE_CASCADE_DELETE; 94 } 95 else if (_cascadeDelete == SOURCE_CASCADE_DELETE) 96 _cascadeDelete = NO_CASCADE_DELETE; 97 } 98 99 102 public void setTargetCascadeDelete(boolean isCascadeDelete) 103 { 104 if (isCascadeDelete) { 105 assert(_cascadeDelete != SOURCE_CASCADE_DELETE); 106 107 _cascadeDelete = TARGET_CASCADE_DELETE; 108 } 109 else if (_cascadeDelete == TARGET_CASCADE_DELETE) 110 _cascadeDelete = NO_CASCADE_DELETE; 111 } 112 113 116 public boolean isSourceCascadeDelete() 117 { 118 return _cascadeDelete == SOURCE_CASCADE_DELETE; 119 } 120 121 124 public boolean isTargetCascadeDelete() 125 { 126 return _cascadeDelete == TARGET_CASCADE_DELETE; 127 } 128 129 132 public Table getSourceTable() 133 { 134 return _sourceTable; 135 } 136 137 140 public Table getTargetTable() 141 { 142 return _targetTable; 143 } 144 145 148 public ArrayList <ForeignColumn> getColumns() 149 { 150 return _columns; 151 } 152 153 156 157 160 public ForeignColumn getSourceColumn(Column targetKey) 161 { 162 for (int i = _columns.size() - 1; i >= 0; i--) { 163 ForeignColumn column = _columns.get(i); 164 165 if (column.getTargetColumn() == targetKey) 166 return column; 167 } 168 169 170 return null; 171 } 172 173 176 public String generateSelectSQL(String table) 177 { 178 CharBuffer cb = new CharBuffer(); 179 180 for (int i = 0; i < _columns.size(); i++) { 181 if (i != 0) 182 cb.append(", "); 183 184 if (table != null) { 185 cb.append(table); 186 cb.append("."); 187 } 188 189 cb.append(_columns.get(i).getName()); 190 } 191 192 return cb.toString(); 193 } 194 195 198 public void generateInsert(ArrayList <String > columns) 199 { 200 for (int i = 0; i < _columns.size(); i++) 201 columns.add(_columns.get(i).getName()); 202 } 203 204 207 public String generateUpdateSQL() 208 { 209 CharBuffer cb = new CharBuffer(); 210 211 for (int i = 0; i < _columns.size(); i++) { 212 if (i != 0) 213 cb.append(", "); 214 215 cb.append(_columns.get(i).getName() + "=?"); 216 } 217 218 return cb.toString(); 219 } 220 221 224 public String generateMatchArgSQL(String table) 225 { 226 CharBuffer cb = new CharBuffer(); 227 228 for (int i = 0; i < _columns.size(); i++) { 229 if (i != 0) 230 cb.append(" and "); 231 232 if (table != null) { 233 cb.append(table); 234 cb.append("."); 235 } 236 237 cb.append(_columns.get(i).getName()); 238 cb.append("=?"); 239 } 240 241 return cb.toString(); 242 } 243 244 250 public String generateJoin(String sourceTable, 251 String targetTable) 252 { 253 return generateJoin(sourceTable, targetTable, false); 254 } 255 256 263 public String generateJoin(String sourceTable, 264 String targetTable, 265 boolean isArg) 266 { 267 CharBuffer cb = new CharBuffer(); 268 269 cb.append('('); 270 271 for (int i = 0; i < _columns.size(); i++) { 272 ForeignColumn column = _columns.get(i); 273 274 if (i != 0) 275 cb.append(" and "); 276 277 cb.append(sourceTable); 278 cb.append('.'); 279 cb.append(column.getName()); 280 281 cb.append(" = "); 282 283 cb.append(targetTable); 284 285 if (isArg) 286 continue; 287 288 cb.append('.'); 289 cb.append(column.getTargetColumn().getName()); 290 } 291 292 cb.append(')'); 293 294 return cb.toString(); 295 } 296 297 308 public String generateJoin(LinkColumns manyToOneJoin, 309 String sourceTable1, 310 String sourceTable2) 311 { 312 314 if (manyToOneJoin._columns.size() != _columns.size()) 315 return ""; 316 317 CharBuffer cb = new CharBuffer(); 318 319 cb.append('('); 320 321 for (int i = 0; i < _columns.size(); i++) { 322 ForeignColumn column = _columns.get(i); 323 ForeignColumn otherColumn = manyToOneJoin._columns.get(i); 324 325 if (i != 0) 326 cb.append(" and "); 327 328 cb.append(sourceTable1); 329 cb.append('.'); 330 cb.append(column.getName()); 331 332 cb.append(" = "); 333 334 cb.append(sourceTable2); 335 336 cb.append('.'); 337 cb.append(otherColumn.getName()); 338 } 339 340 cb.append(')'); 341 342 return cb.toString(); 343 } 344 345 351 public String generateWhere(String sourceTable, 352 String targetTable) 353 { 354 CharBuffer cb = new CharBuffer(); 355 356 cb.append('('); 357 358 for (int i = 0; i < _columns.size(); i++) { 359 ForeignColumn column = _columns.get(i); 360 361 if (i != 0) 362 cb.append(" and "); 363 364 if (! column.isNotNull()) { 365 366 if (sourceTable == null) 367 cb.append('?'); 368 else { 369 cb.append(sourceTable); 370 cb.append('.'); 371 cb.append(column.getName()); 372 } 373 374 cb.append(" is not null "); 375 } 376 377 cb.append(" and "); 378 379 if (sourceTable == null) { 381 cb.append('?'); 382 } 383 else { 384 cb.append(sourceTable); 385 cb.append('.'); 386 cb.append(column.getName()); 387 } 388 389 cb.append(" = "); 390 391 cb.append(targetTable); 392 cb.append('.'); 393 cb.append(column.getTargetColumn().getName()); 394 } 395 396 cb.append(')'); 397 398 return cb.toString(); 399 } 400 401 404 public void beforeTargetDelete(AmberConnection aConn, Entity entity) 405 throws SQLException 406 { 407 410 String sourceTable = _sourceTable.getName(); 411 412 if (! isSourceCascadeDelete()) { 413 CharBuffer cb = new CharBuffer(); 414 415 cb.append("update " + sourceTable + " set "); 416 417 ArrayList <ForeignColumn> columns = getColumns(); 418 419 for (int i = 0; i < columns.size(); i++) { 420 if (i != 0) 421 cb.append (", "); 422 423 cb.append(columns.get(i).getName() + "=null"); 424 } 425 426 cb.append(" where "); 427 428 for (int i = 0; i < columns.size(); i++) { 429 if (i != 0) 430 cb.append (" and "); 431 432 cb.append(columns.get(i).getName() + "=?"); 433 } 434 435 PreparedStatement pstmt = aConn.prepareStatement(cb.toString()); 436 437 entity.__caucho_setKey(pstmt, 1); 438 439 pstmt.executeUpdate(); 440 441 aConn.addCompletion(_sourceTable.getUpdateCompletion()); 442 } 443 else if (_sourceTable.isCascadeDelete()) { 444 451 EntityType entityType = (EntityType) _sourceTable.getType(); 452 453 CharBuffer cb = new CharBuffer(); 454 455 cb.append("select "); 456 cb.append(entityType.getId().generateSelect("o")); 457 cb.append(" from " + sourceTable + " o"); 458 cb.append(" where "); 459 460 ArrayList <ForeignColumn> columns = getColumns(); 461 462 for (int i = 0; i < columns.size(); i++) { 463 if (i != 0) 464 cb.append (" and "); 465 466 cb.append(columns.get(i).getName() + "=?"); 467 } 468 469 PreparedStatement pstmt = aConn.prepareStatement(cb.toString()); 470 471 entity.__caucho_setKey(pstmt, 1); 472 473 ArrayList <Object > proxyList = new ArrayList <Object >(); 474 475 ResultSet rs = pstmt.executeQuery(); 476 while (rs.next()) { 477 proxyList.add(entityType.getHome().loadLazy(aConn, rs, 1)); 478 } 479 rs.close(); 480 481 for (Object obj : proxyList) { 482 entityType.getHome().getEntityFactory().delete(aConn, obj); 483 } 484 } 485 else { 486 CharBuffer cb = new CharBuffer(); 487 488 cb.append("delete from " + sourceTable + 489 " where "); 490 491 ArrayList <ForeignColumn> columns = getColumns(); 492 493 for (int i = 0; i < columns.size(); i++) { 494 if (i != 0) 495 cb.append (" and "); 496 497 cb.append(columns.get(i).getName() + "=?"); 498 } 499 500 PreparedStatement pstmt = aConn.prepareStatement(cb.toString()); 501 502 entity.__caucho_setKey(pstmt, 1); 503 504 pstmt.executeUpdate(); 505 506 aConn.addCompletion(_sourceTable.getDeleteCompletion()); 507 } 508 509 aConn.expire(); 510 } 511 512 515 public void afterSourceDelete(AmberConnection aConn, Entity entity) 516 throws SQLException 517 { 518 } 520 521 public String toString() 522 { 523 return "[" + _sourceTable + ", " + _targetTable + ", " + _columns + "]"; 524 } 525 } 526 | Popular Tags |