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 }