| 1 package org.apache.torque.util; 2 3 21 22 import java.io.Serializable ; 23 import java.sql.Connection ; 24 import java.sql.PreparedStatement ; 25 import java.sql.SQLException ; 26 import java.sql.Statement ; 27 import java.util.ArrayList ; 28 import java.util.Collections ; 29 import java.util.HashSet ; 30 import java.util.Iterator ; 31 import java.util.List ; 32 import java.util.Map ; 33 import java.util.Set ; 34 35 import org.apache.commons.lang.StringUtils; 36 import org.apache.commons.logging.Log; 37 import org.apache.commons.logging.LogFactory; 38 import org.apache.torque.Database; 39 import org.apache.torque.Torque; 40 import org.apache.torque.TorqueException; 41 import org.apache.torque.adapter.DB; 42 import org.apache.torque.map.ColumnMap; 43 import org.apache.torque.map.DatabaseMap; 44 import org.apache.torque.map.MapBuilder; 45 import org.apache.torque.map.TableMap; 46 import org.apache.torque.oid.IdGenerator; 47 import org.apache.torque.om.NumberKey; 48 import org.apache.torque.om.ObjectKey; 49 import org.apache.torque.om.SimpleKey; 50 import org.apache.torque.om.StringKey; 51 52 import com.workingdogs.village.Column; 53 import com.workingdogs.village.DataSet; 54 import com.workingdogs.village.DataSetException; 55 import com.workingdogs.village.KeyDef; 56 import com.workingdogs.village.QueryDataSet; 57 import com.workingdogs.village.Record; 58 import com.workingdogs.village.Schema; 59 import com.workingdogs.village.TableDataSet; 60 61 78 public abstract class BasePeer 79 implements Serializable  80 { 81 82 public static final String ORDER_BY = "ORDER BY"; 83 84 88 public static final String IGNORE_CASE = "IgNOrE cAsE"; 89 90 91 public static final String TABLE_NAME = "TABLE_NAME"; 92 93 94 protected static final Log log = LogFactory.getLog(BasePeer.class); 95 96 private static void throwTorqueException(Exception e) 97 throws TorqueException 98 { 99 if (e instanceof TorqueException) 100 { 101 throw (TorqueException) e; 102 } 103 else 104 { 105 throw new TorqueException(e); 106 } 107 } 108 109 116 public static Schema initTableSchema(String tableName) 117 { 118 return initTableSchema(tableName, Torque.getDefaultDB()); 119 } 120 121 130 public static Schema initTableSchema(String tableName, String dbName) 131 { 132 Schema schema = null; 133 Connection con = null; 134 135 try 136 { 137 con = Torque.getConnection(dbName); 138 schema = new Schema().schema(con, tableName); 139 } 140 catch (Exception e) 141 { 142 log.error(e); 143 throw new Error ("Error in BasePeer.initTableSchema(" 144 + tableName 145 + "): " 146 + e.getMessage()); 147 } 148 finally 149 { 150 Torque.closeConnection(con); 151 } 152 return schema; 153 } 154 155 161 public static Column[] initTableColumns(Schema schema) 162 { 163 Column[] columns = null; 164 try 165 { 166 int numberOfColumns = schema.numberOfColumns(); 167 columns = new Column[numberOfColumns]; 168 for (int i = 0; i < numberOfColumns; i++) 169 { 170 columns[i] = schema.column(i + 1); 171 } 172 } 173 catch (Exception e) 174 { 175 log.error(e); 176 throw new Error ( 177 "Error in BasePeer.initTableColumns(): " + e.getMessage()); 178 } 179 return columns; 180 } 181 182 188 public static String [] initColumnNames(Column[] columns) 189 { 190 String [] columnNames = new String [columns.length]; 191 for (int i = 0; i < columns.length; i++) 192 { 193 columnNames[i] = columns[i].name().toUpperCase(); 194 } 195 return columnNames; 196 } 197 198 205 public static String [] initCriteriaKeys( 206 String tableName, 207 String [] columnNames) 208 { 209 String [] keys = new String [columnNames.length]; 210 for (int i = 0; i < columnNames.length; i++) 211 { 212 keys[i] = tableName + "." + columnNames[i].toUpperCase(); 213 } 214 return keys; 215 } 216 217 229 public static void deleteAll( 230 Connection con, 231 String table, 232 String column, 233 int value) 234 throws TorqueException 235 { 236 Statement statement = null; 237 try 238 { 239 statement = con.createStatement(); 240 241 StringBuffer query = new StringBuffer (); 242 query.append("DELETE FROM ") 243 .append(table) 244 .append(" WHERE ") 245 .append(column) 246 .append(" = ") 247 .append(value); 248 249 statement.executeUpdate(query.toString()); 250 } 251 catch (SQLException e) 252 { 253 throw new TorqueException(e); 254 } 255 finally 256 { 257 if (statement != null) 258 { 259 try 260 { 261 statement.close(); 262 } 263 catch (SQLException e) 264 { 265 throw new TorqueException(e); 266 } 267 } 268 } 269 } 270 271 283 public static void deleteAll(String table, String column, int value) 284 throws TorqueException 285 { 286 Connection con = null; 287 try 288 { 289 con = Torque.getConnection(Torque.getDefaultDB()); 291 deleteAll(con, table, column, value); 292 } 293 finally 294 { 295 Torque.closeConnection(con); 296 } 297 } 298 299 307 public static void doDelete(Criteria criteria) throws TorqueException 308 { 309 Connection con = null; 310 try 311 { 312 con = Transaction.beginOptional( 313 criteria.getDbName(), 314 criteria.isUseTransaction()); 315 doDelete(criteria, con); 316 Transaction.commit(con); 317 } 318 catch (TorqueException e) 319 { 320 Transaction.safeRollback(con); 321 throw e; 322 } 323 } 324 325 333 public static void doDelete(Criteria criteria, Connection con) 334 throws TorqueException 335 { 336 String dbName = criteria.getDbName(); 337 final DatabaseMap dbMap = Torque.getDatabaseMap(dbName); 338 339 SQLBuilder.TableCallback tc = new SQLBuilder.TableCallback() { 344 public void process (Set tables, String key, Criteria crit) 345 { 346 if (crit.isCascade()) 347 { 348 TableMap[] tableMaps = dbMap.getTables(); 350 for (int i = 0; i < tableMaps.length; i++) 351 { 352 ColumnMap[] columnMaps = tableMaps[i].getColumns(); 353 354 for (int j = 0; j < columnMaps.length; j++) 355 { 356 if (columnMaps[j].isForeignKey() 360 && columnMaps[j].isPrimaryKey() 361 && key.equals(columnMaps[j].getRelatedName())) 362 { 363 tables.add(tableMaps[i].getName()); 364 crit.add(columnMaps[j].getFullyQualifiedName(), 365 crit.getValue(key)); 366 } 367 } 368 } 369 } 370 } 371 }; 372 373 Set tables = SQLBuilder.getTableSet(criteria, tc); 374 375 try 376 { 377 processTables(criteria, tables, con, new ProcessCallback() { 378 public void process(String table, String dbName, Record rec) 379 throws Exception  380 { 381 rec.markToBeDeleted(); 382 rec.save(); 383 } 384 }); 385 } 386 catch (Exception e) 387 { 388 throwTorqueException(e); 389 } 390 } 391 392 416 public static ObjectKey doInsert(Criteria criteria) throws TorqueException 417 { 418 Connection con = null; 419 ObjectKey id = null; 420 421 try 422 { 423 con = Transaction.beginOptional( 424 criteria.getDbName(), 425 criteria.isUseTransaction()); 426 id = doInsert(criteria, con); 427 Transaction.commit(con); 428 } 429 catch (TorqueException e) 430 { 431 Transaction.safeRollback(con); 432 throw e; 433 } 434 435 return id; 436 } 437 438 463 public static ObjectKey doInsert(Criteria criteria, Connection con) 464 throws TorqueException 465 { 466 SimpleKey id = null; 467 468 String table = null; 471 Iterator keys = criteria.keySet().iterator(); 472 if (keys.hasNext()) 473 { 474 table = criteria.getTableName((String ) keys.next()); 475 } 476 else 477 { 478 throw new TorqueException("Database insert attempted without " 479 + "anything specified to insert"); 480 } 481 482 String dbName = criteria.getDbName(); 483 Database database = Torque.getDatabase(dbName); 484 DatabaseMap dbMap = database.getDatabaseMap(); 485 TableMap tableMap = dbMap.getTable(table); 486 Object keyInfo = tableMap.getPrimaryKeyMethodInfo(); 487 IdGenerator keyGen 488 = database.getIdGenerator(tableMap.getPrimaryKeyMethod()); 489 490 ColumnMap pk = getPrimaryKey(criteria); 491 492 if (keyGen != null && keyGen.isPriorToInsert()) 495 { 496 if (pk != null && !criteria.containsKey(pk.getFullyQualifiedName())) 499 { 500 id = getId(pk, keyGen, con, keyInfo); 501 criteria.add(pk.getFullyQualifiedName(), id); 502 } 503 } 504 505 TableDataSet tds = null; 507 try 508 { 509 String tableName = SQLBuilder.getFullTableName(table, dbName); 510 tds = new TableDataSet(con, tableName); 511 Record rec = tds.addRecord(); 512 BasePeer.insertOrUpdateRecord(rec, table, dbName, criteria); 514 } 515 catch (DataSetException e) 516 { 517 throwTorqueException(e); 518 } 519 catch (SQLException e) 520 { 521 throwTorqueException(e); 522 } 523 catch (TorqueException e) 524 { 525 throwTorqueException(e); 526 } 527 finally 528 { 529 VillageUtils.close(tds); 530 } 531 532 if (keyGen != null && keyGen.isPostInsert()) 535 { 536 id = getId(pk, keyGen, con, keyInfo); 537 } 538 539 return id; 540 } 541 542 553 private static SimpleKey getId(ColumnMap pk, IdGenerator keyGen, Connection con, Object keyInfo) 554 throws TorqueException 555 { 556 SimpleKey id = null; 557 558 try 559 { 560 if (pk != null && keyGen != null) 561 { 562 if (pk.getType() instanceof Number ) 563 { 564 id = new NumberKey( 565 keyGen.getIdAsBigDecimal(con, keyInfo)); 566 } 567 else 568 { 569 id = new StringKey(keyGen.getIdAsString(con, keyInfo)); 570 } 571 } 572 } 573 catch (Exception e) 574 { 575 throwTorqueException(e); 576 } 577 return id; 578 } 579 580 590 private static void insertOrUpdateRecord( 591 Record rec, 592 String table, 593 String dbName, 594 Criteria criteria) 595 throws TorqueException 596 { 597 DatabaseMap dbMap = Torque.getDatabaseMap(dbName); 598 599 ColumnMap[] columnMaps = dbMap.getTable(table).getColumns(); 600 boolean shouldSave = false; 601 for (int j = 0; j < columnMaps.length; j++) 602 { 603 ColumnMap colMap = columnMaps[j]; 604 String colName = colMap.getColumnName(); 605 String key = new StringBuffer (colMap.getTableName()) 606 .append('.') 607 .append(colName) 608 .toString(); 609 if (criteria.containsKey(key)) 610 { 611 try 612 { 613 VillageUtils.setVillageValue(criteria, key, rec, colName); 614 shouldSave = true; 615 } 616 catch (Exception e) 617 { 618 throwTorqueException(e); 619 } 620 } 621 } 622 623 if (shouldSave) 624 { 625 try 626 { 627 rec.save(); 628 } 629 catch (Exception e) 630 { 631 throwTorqueException(e); 632 } 633 } 634 else 635 { 636 throw new TorqueException("No changes to save"); 637 } 638 } 639 640 648 static String createQueryDisplayString(Criteria criteria) 649 throws TorqueException 650 { 651 return createQuery(criteria).toString(); 652 } 653 654 662 public static String createQueryString(Criteria criteria) 663 throws TorqueException 664 { 665 Query query = createQuery(criteria); 666 return query.toString(); 667 } 668 669 678 static Query createQuery(Criteria criteria) 679 throws TorqueException 680 { 681 return SQLBuilder.buildQueryClause(criteria, null, new SQLBuilder.QueryCallback() { 682 public String process(Criteria.Criterion criterion, List params) 683 { 684 return criterion.toString(); 685 } 686 }); 687 } 688 689 697 public static List doSelect(Criteria criteria) throws TorqueException 698 { 699 Connection con = null; 700 List results = null; 701 702 try 703 { 704 con = Transaction.beginOptional( 705 criteria.getDbName(), 706 criteria.isUseTransaction()); 707 results = doSelect(criteria, con); 708 Transaction.commit(con); 709 } 710 catch (TorqueException e) 711 { 712 Transaction.safeRollback(con); 713 throw e; 714 } 715 return results; 716 } 717 718 727 public static List doSelect(Criteria criteria, Connection con) 728 throws TorqueException 729 { 730 Query query = createQuery(criteria); 731 DB dbadapter = Torque.getDB(criteria.getDbName()); 732 733 return executeQuery(query.toString(), 735 dbadapter.supportsNativeOffset() ? 0 : criteria.getOffset(), 736 dbadapter.supportsNativeLimit() ? -1 : criteria.getLimit(), 737 criteria.isSingleRecord(), 738 con); 739 } 740 741 751 public static List executeQuery(String queryString) throws TorqueException 752 { 753 return executeQuery(queryString, Torque.getDefaultDB(), false); 754 } 755 756 767 public static List executeQuery(String queryString, String dbName) 768 throws TorqueException 769 { 770 return executeQuery(queryString, dbName, false); 771 } 772 773 784 public static List executeQuery( 785 String queryString, 786 String dbName, 787 boolean singleRecord) 788 throws TorqueException 789 { 790 return executeQuery(queryString, 0, -1, dbName, singleRecord); 791 } 792 793 804 public static List executeQuery( 805 String queryString, 806 boolean singleRecord, 807 Connection con) 808 throws TorqueException 809 { 810 return executeQuery(queryString, 0, -1, singleRecord, con); 811 } 812 813 826 public static List executeQuery( 827 String queryString, 828 int start, 829 int numberOfResults, 830 String dbName, 831 boolean singleRecord) 832 throws TorqueException 833 { 834 Connection con = null; 835 List results = null; 836 try 837 { 838 con = Torque.getConnection(dbName); 839 results = executeQuery( 841 queryString, 842 start, 843 &nb
|