001 package hirondelle.web4j.database; 002 003 import hirondelle.web4j.model.Id; 004 import java.sql.Connection; 005 import java.util.ArrayList; 006 import java.util.Collections; 007 import java.util.List; 008 009 /** 010 Version of {@link Db} for use in a transaction. 011 012 <P>The {@link Db} class uses an internal connection to execute single operations. 013 If more than one operation needs to be performed as an atomic transaction, then 014 this class is used instead. 015 016 <P>This class is identical to {@link Db}, except that it uses a {@link Connection} passed 017 by the caller. 018 019 <h3><a name="Parameters"></a>SQL Parameters</h3> 020 The parameters for SQL statements used by this class have the same behavior as defined by 021 the <a href='Db.html#Parameters'>Db class</a>. 022 */ 023 public final class DbTx { 024 025 /** 026 <tt>SELECT</tt> operation which returns a single Model Object. 027 028 @param aConnection single connection shared by all operations in the transaction. 029 @param aClass class of the returned Model Object. 030 @param aSqlId identifies the underlying SQL statement. 031 @param aParams <a href="#Parameters">parameters</a> for the SQL statement. 032 */ 033 public static <T> T fetch(Connection aConnection, Class<T> aClass, SqlId aSqlId, Object... aParams) throws DAOException { 034 SqlFetcher fetcher = SqlFetcher.forTx(aSqlId, aConnection, aParams); 035 ModelFromRow<T> builder = new ModelFromRow<T>(aClass); 036 return fetcher.fetchObject(builder); 037 } 038 039 /** 040 <tt>SELECT</tt> operation which returns a single 'building block' value such as <tt>Integer</tt>, <tt>BigDecimal</tt>, and so on. 041 042 @param aConnection single connection shared by all operations in the transaction. 043 @param aSupportedTargetClass class supported by the configured 044 implementation of {@link ConvertColumn}. 045 @param aSqlId identifies the underlying SQL statement. 046 @param aParams <a href="#Parameters">parameters</a> for the SQL statement. 047 */ 048 public static <T> T fetchValue(Connection aConnection, Class<T> aSupportedTargetClass, SqlId aSqlId, Object... aParams) throws DAOException { 049 SqlFetcher fetcher = SqlFetcher.forTx(aSqlId, aConnection, aParams); 050 ModelBuilder<T> builder = new ValueFromRow<T>(aSupportedTargetClass); 051 return fetcher.fetchObject(builder); 052 } 053 054 /** 055 <tt>SELECT</tt> operation which returns <tt>0..N</tt> Model Objects, one per row. 056 057 @param aConnection single connection shared by all operations in the transaction. 058 @param aClass class of the returned Model Objects. 059 @param aSqlId identifies the underlying SQL statement. 060 @param aParams <a href="#Parameters">parameters</a> for the SQL statement. 061 @return an unmodifiable {@link List} of Model Objects. The list may be empty. 062 */ 063 public static <T> List<T> list(Connection aConnection, Class<T> aClass, SqlId aSqlId, Object... aParams) throws DAOException { 064 List<T> result = new ArrayList<T>(); 065 SqlFetcher fetcher = SqlFetcher.forTx(aSqlId, aConnection, aParams); 066 ModelBuilder<T> builder = new ModelFromRow<T>(aClass); 067 fetcher.fetchObjects(builder, result); 068 return Collections.unmodifiableList(result); 069 } 070 071 /** 072 <tt>SELECT</tt> operation which returns a <tt>List</tt> of 'building block' values such 073 as <tt>Integer</tt>, <tt>BigDecimal</tt>, and so on. 074 075 @param aConnection single connection shared by all operations in the transaction. 076 @param aSupportedTargetClass class supported by the configured 077 implementation of {@link ConvertColumn}. 078 @param aSqlId identifies the underlying SQL statement. 079 @param aParams <a href="#Parameters">parameters</a> for the SQL statement. 080 @return an unmodifiable {@link List} of building block objects. The list may be empty. 081 */ 082 public static <T> List<T> listValues(Connection aConnection, Class<T> aSupportedTargetClass, SqlId aSqlId, Object... aParams) throws DAOException { 083 List<T> result = new ArrayList<T>(); 084 SqlFetcher fetcher = SqlFetcher.forTx(aSqlId, aConnection, aParams); 085 ModelBuilder<T> builder = new ValueFromRow<T>(aSupportedTargetClass); 086 fetcher.fetchObjects(builder, result); 087 return Collections.unmodifiableList(result); 088 } 089 090 /** 091 <tt>SELECT</tt> operation that returns a <tt>List</tt> of Model Objects "subsetted" to 092 a particular range of rows. 093 094 <P>This method is intended for paging through long listings. When the underlying 095 <tt>SELECT</tt> returns many pages of items, the records can be "subsetted" by 096 calling this method. 097 098 <P>See {@link hirondelle.web4j.ui.tag.Pager}. 099 @param aConnection single connection shared by all operations in the transaction. 100 @param aClass class of the returned Model Objects. 101 @param aSqlId identifies the underlying SQL statement. 102 @param aStartIndex 1-based index indentifying the first row to be returned. 103 @param aPageSize number of records to be returned. 104 @param aParams <a href="#Parameters">parameters</a> for the SQL statement. 105 @return an unmodifiable {@link List} of Model Objects. The list may be empty. 106 */ 107 public static <T> List<T> listRange(Connection aConnection, Class<T> aClass, SqlId aSqlId, Integer aStartIndex, Integer aPageSize, Object... aParams) throws DAOException { 108 List<T> result = new ArrayList<T>(); 109 SqlFetcher fetcher = SqlFetcher.forTx(aSqlId, aConnection, aParams); 110 fetcher.limitRowsToRange(aStartIndex, aPageSize); 111 ModelBuilder<T> builder = new ModelFromRow<T>(aClass); 112 fetcher.fetchObjects(builder, result); 113 return Collections.unmodifiableList(result); 114 } 115 116 /** 117 <tt>INSERT</tt>, <tt>UPDATE</tt>, or <tt>DELETE</tt> operations which take parameters. 118 119 @param aConnection single connection shared by all operations in the transaction. 120 @param aSqlId identifies the underlying SQL statement. 121 @param aParams <a href="#Parameters">parameters</a> for the SQL statement. 122 @return the number of records affected by this edit operation. 123 */ 124 public static int edit(Connection aConnection, SqlId aSqlId, Object... aParams) throws DAOException, DuplicateException { 125 SqlEditor change = SqlEditor.forTx(aSqlId, aConnection, aParams); 126 return change.editDatabase(); 127 } 128 129 /** 130 <tt>INSERT</tt> operation which returns the database identifier of the added record. 131 132 <P>This operation is not supported by all databases. See 133 {@link java.sql.Statement} for more information. 134 135 @param aConnection single connection shared by all operations in the transaction. 136 @param aSqlId identifies the underlying SQL statement. 137 @param aParams <a href="#Parameters">parameters</a> for the SQL statement. 138 */ 139 public static Id add(Connection aConnection, SqlId aSqlId, Object... aParams) throws DAOException, DuplicateException { 140 SqlEditor add = SqlEditor.forTx(aSqlId, aConnection, aParams); 141 return new Id(add.addRecord()); 142 } 143 144 /** 145 <tt>DELETE</tt> operation which takes parameters. 146 147 @param aConnection single connection shared by all operations in the transaction. 148 @param aSqlId identifies the underlying SQL statement. 149 @param aParams identifies the item to be deleted. Often 1 or more {@link Id} objects. 150 @return the number of deleted records. 151 */ 152 public static int delete(Connection aConnection, SqlId aSqlId, Object... aParams) throws DAOException { 153 SqlEditor delete = SqlEditor.forTx(aSqlId, aConnection, aParams); 154 return delete.editDatabase(); 155 } 156 157 /** 158 <tt>SELECT</tt> operation which typically returns a single item with a <tt>0..N</tt> relation. 159 160 <P>The <tt>ResultSet</tt> is parsed into a single parent Model Object having a <tt>List</tt> of 161 <tt>0..N</tt> child Model Objects. 162 See note on <a href="#CompundObjects">compound objects</a> for more information. 163 164 @param aConnection single connection shared by all operations in the transaction. 165 @param aClassParent class of the parent Model Object. 166 @param aClassChild class of the child Model Object. 167 @param aNumTrailingColsForChildList number of columns appearing at the end of the <tt>ResultSet</tt> which 168 are passed to the <em>child</em> constructor. 169 @param aSqlId identifies the underlying SQL statement. 170 @param aParams <a href="#Parameters">parameters</a> to the underlying SQL statement. 171 */ 172 public static <T> T fetchCompound(Connection aConnection, Class<T> aClassParent, Class<?> aClassChild, int aNumTrailingColsForChildList, SqlId aSqlId, Object... aParams) throws DAOException { 173 SqlFetcher fetcher = SqlFetcher.forTx(aSqlId, aConnection, aParams); 174 ModelBuilder<T> builder = new ModelFromRow<T>(aClassParent, aClassChild, aNumTrailingColsForChildList); 175 return fetcher.fetchObject(builder); 176 } 177 178 /** 179 <tt>SELECT</tt> operation which typically returns mutliple items item with a <tt>0..N</tt> relation. 180 181 <P>The <tt>ResultSet</tt> is parsed into a <tt>List</tt> of parent Model Objects, each having <tt>0..N</tt> 182 child Model Objects. See note on <a href="#CompundObjects">compound objects</a> for more information. 183 184 @param aConnection single connection shared by all operations in the transaction. 185 @param aClassParent class of the parent Model Object. 186 @param aClassChild class of the child Model Object. 187 @param aNumTrailingColsForChildList number of columns appearing at the end of the <tt>ResultSet</tt> which 188 are passed to the <em>child</em> constructor. 189 @param aSqlId identifies the underlying SQL statement. 190 @param aParams <a href="#Parameters">parameters</a> to the underlying SQL statement. 191 */ 192 public static <T> List<T> listCompound(Connection aConnection, Class<T> aClassParent, Class<?> aClassChild, int aNumTrailingColsForChildList, SqlId aSqlId, Object... aParams) throws DAOException { 193 List<T> result = new ArrayList<T>(); 194 SqlFetcher fetcher = SqlFetcher.forTx(aSqlId, aConnection, aParams); 195 ModelBuilder<T> builder = new ModelFromRow<T>(aClassParent, aClassChild, aNumTrailingColsForChildList); 196 fetcher.fetchObjects(builder, result); 197 return result; 198 } 199 200 // PRIVATE 201 202 private DbTx() { 203 //prevent construction by the caller 204 } 205 }