View Javadoc
1   package com.atlassian.activeobjects.external;
2   
3   import com.atlassian.sal.api.transaction.TransactionCallback;
4   import net.java.ao.Accessor;
5   import net.java.ao.DBParam;
6   import net.java.ao.EntityStreamCallback;
7   import net.java.ao.Query;
8   import net.java.ao.RawEntity;
9   
10  import java.util.Map;
11  
12  /**
13   * Interface to the active objects framework. Instance is threadsafe.
14   */
15  public interface ActiveObjects {
16      /**
17       * Creates the schema for the specified entities
18       */
19      void migrate(Class<? extends RawEntity<?>>... entities);
20  
21      /**
22       * Create the schema for the specified entities, dropping columns and tables which are no longer required
23       */
24      void migrateDestructively(Class<? extends RawEntity<?>>... entities);
25  
26      /**
27       * Flushes all value caches contained within entities controlled by this {@code EntityManager}
28       * instance.  This does not actually remove the entities from the instance cache maintained
29       * within this class.  Rather, it simply dumps all of the field values cached within the entities
30       * themselves (with the exception of the primary key value).  This should be used in the case
31       * of a complex process outside AO control which may have changed values in the database.  If
32       * it is at all possible to determine precisely which rows have been changed, the
33       * {@link #flush(net.java.ao.RawEntity...)} method should be used instead.
34       */
35      void flushAll();
36  
37      /**
38       * Flushes the value caches of the specified entities along with all of the relevant
39       * relations cache entries.  This should be called after a process outside of AO control
40       * may have modified the values in the specified rows.  This does not actually remove
41       * the entity instances themselves from the instance cache.  Rather, it just flushes all
42       * of their internally cached values (with the exception of the primary key).
43       */
44      void flush(RawEntity<?>... entities);
45  
46      /**
47       * Returns an array of entities of the specified type corresponding to the
48       * varargs primary keys. If an in-memory reference already exists to a corresponding
49       * entity (of the specified type and key), it is returned rather than creating
50       * a new instance.
51       * <p>
52       * No checks are performed to ensure that the key actually exists in the
53       * database for the specified object. Thus, this method is solely a Java
54       * memory state modifying method. There is no database access involved.
55       * The upshot of this is that the method is very very fast.  The flip side of
56       * course is that one could conceivably maintain entities which reference
57       * non-existent database rows.
58       *
59       * @param type The type of the entities to retrieve
60       * @param keys The primary keys corresponding to the entities to retrieve.  All
61       *             keys must be typed according to the generic type parameter of the entity's
62       *             {@link RawEntity} inheritance (if inheriting from {@link net.java.ao.Entity}, this is {@code Integer}
63       *             or {@code int}). Thus, the {@code keys} array is type-checked at compile time.
64       * @return An array of entities of the given type corresponding with the specified primary keys
65       */
66      @SuppressWarnings("unchecked")
67      <T extends RawEntity<K>, K> T[] get(Class<T> type, K... keys);
68  
69      /**
70       * Cleverly overloaded method to return a single entity of the specified type
71       * rather than an array in the case where only one ID is passed.  This method
72       * merely delegates the call to the overloaded <code>get</code> method
73       * and functions as syntactical sugar.
74       *
75       * @param type The type of the entity instance to retrieve
76       * @param key  The primary key corresponding to the entity to be retrieved
77       * @return An entity instance of the given type corresponding to the specified primary key
78       * @see #get(Class, Object...)
79       */
80      <T extends RawEntity<K>, K> T get(Class<T> type, K key);
81  
82      /**
83       * Creates a new entity of the specified type with the optionally specified
84       * initial parameters.  This method actually inserts a row into the table represented
85       * by the entity type and returns the entity instance which corresponds to that
86       * row.
87       * <p>
88       * The {@link net.java.ao.DBParam} object parameters are designed to allow the creation
89       * of entities which have non-null fields which have no defalut or auto-generated
90       * value.  Insertion of a row without such field values would of course fail,
91       * thus the need for db params.  The db params can also be used to set
92       * the values for any field in the row, leading to more compact code under
93       * certain circumstances.
94       * <p>
95       * Unless within a transaction, this method will commit to the database
96       * immediately and exactly once per call.  Thus, care should be taken in
97       * the creation of large numbers of entities.  There doesn't seem to be a more
98       * efficient way to create large numbers of entities, however one should still
99       * be aware of the performance implications.
100      * <p>
101      * This method delegates the action INSERT action to
102      * This is necessary because not all databases support the JDBC <code>RETURN_GENERATED_KEYS</code>
103      * constant (e.g. PostgreSQL and HSQLDB).  Thus, the database provider itself is
104      * responsible for handling INSERTion and retrieval of the correct primary key
105      * value.
106      *
107      * @param type   The type of the entity to INSERT
108      * @param params An optional varargs array of initial values for the fields in the row. These
109      *               values will be passed to the database within the INSERT statement.
110      * @return The new entity instance corresponding to the INSERTed row
111      * @see net.java.ao.DBParam
112      */
113     <T extends RawEntity<K>, K> T create(Class<T> type, DBParam... params);
114 
115     /**
116      * Creates and INSERTs a new entity of the specified type with the given map of
117      * parameters.  This method merely delegates to the {@link #create(Class, DBParam...)}
118      * method.  The idea behind having a separate convenience method taking a map is in
119      * circumstances with large numbers of parameters or for people familiar with the
120      * anonymous inner class constructor syntax who might be more comfortable with
121      * creating a map than with passing a number of objects.
122      *
123      * @param type   The type of the entity to INSERT
124      * @param params A map of parameters to pass to the INSERT
125      * @return The new entity instance corresponding to the INSERTed row
126      * @see #create(Class, DBParam...)
127      */
128     <T extends RawEntity<K>, K> T create(Class<T> type, Map<String, Object> params);
129 
130     /**
131      * Deletes the specified entities from the database.  DELETE statements are
132      * called on the rows in the corresponding tables and the entities are removed
133      * from the instance cache.  The entity instances themselves are not invalidated,
134      * but it doesn't even make sense to continue using the instance without a row
135      * with which it is paired.
136      * <p>
137      * This method does attempt to group the DELETE statements on a per-type
138      * basis.  Thus, if you pass 5 instances of <code>EntityA</code> and two
139      * instances of <code>EntityB</code>, the following SQL prepared statements
140      * will be invoked:
141      * <pre>
142      *     DELETE FROM entityA WHERE id IN (?,?,?,?,?);
143      *     DELETE FROM entityB WHERE id IN (?,?);
144      * </pre>
145      * Thus, this method scales very well for large numbers of entities grouped
146      * into types. However, the execution time increases linearly for each entity of
147      * unique type.
148      *
149      * @param entities A varargs array of entities to delete. Method returns immediately if length == 0.
150      */
151     @SuppressWarnings("unchecked")
152     void delete(RawEntity<?>... entities);
153 
154     /**
155      * Deletes rows from the table corresponding to {@code type}. In contrast to {@link #delete(RawEntity[])},
156      * this method allows you to delete rows without creating entities for them first.
157      * <p>
158      * Example:
159      * <pre>
160      *     manager.deleteWithSQL(Person.class, "name = ?", "Charlie")
161      * </pre>
162      * The SQL in {@code criteria} is not parsed or modified in any way by ActiveObjects, and is simply appended
163      * to the DELETE statement in a WHERE clause. The above example would cause an SQL statement similar to the
164      * following to be executed:
165      * <pre>
166      *     DELETE FROM people WHERE name = 'Charlie';
167      * </pre>
168      * If {@code criteria} is {@code null}, this method deletes all rows from the table corresponding to {@code type}.
169      * <p>
170      * This method does not attempt to determine the set of entities affected by the statement. As such, it is
171      * recommended that you call {@link #flushAll()} after calling this method.
172      *
173      * @param type       The entity type corresponding to the table to delete from
174      * @param criteria   An optional SQL fragment specifying which rows to delete
175      * @param parameters A varargs array of parameters to be passed to the executed prepared statement. The length
176      *                   of this array <i>must</i> match the number of parameters (denoted by the '?' char) in {@code criteria}.
177      * @return The number of rows deleted from the table
178      * @see #delete(RawEntity...)
179      * @see #find(Class, String, Object...)
180      * @see #findWithSQL(Class, String, String, Object...)
181      */
182     <K> int deleteWithSQL(Class<? extends RawEntity<K>> type, String criteria, Object... parameters);
183 
184     /**
185      * Returns all entities of the given type.  This actually peers the call to
186      * the {@link #find(Class, net.java.ao.Query)} method.
187      *
188      * @param type The type of entity to retrieve
189      * @return An array of all entities which correspond to the given type
190      */
191     <T extends RawEntity<K>, K> T[] find(Class<T> type);
192 
193     /**
194      * Convenience method to select all entities of the given type with the
195      * specified, parameterized criteria.  The <code>criteria</code> String
196      * specified is appended to the SQL prepared statement immediately
197      * following the <code>WHERE</code>.
198      * <p>
199      * Example:
200      * <pre>
201      *     manager.find(Person.class, "name LIKE ? OR age &gt; ?", "Joe", 9);
202      * </pre>
203      * This actually delegates the call to the {@link #find(Class, net.java.ao.Query)}
204      * method, properly parameterizing the {@link net.java.ao.Query} object.
205      *
206      * @param type       The type of the entities to retrieve
207      * @param criteria   A parameterized WHERE statement used to determine the results
208      * @param parameters A varargs array of parameters to be passed to the executed
209      *                   prepared statement.  The length of this array <i>must</i> match the number of
210      *                   parameters (denoted by the '?' char) in the <code>criteria</code>.
211      * @return An array of entities of the given type which match the specified criteria
212      */
213     <T extends RawEntity<K>, K> T[] find(Class<T> type, String criteria, Object... parameters);
214 
215     /**
216      * Selects all entities matching the given type and {@link net.java.ao.Query}.  By default, the
217      * entities will be created based on the values within the primary key field for the
218      * specified type (this is usually the desired behavior).
219      * <p>
220      * Example:
221      * <pre>
222      *     manager.find(Person.class, Query.select().where("name LIKE ? OR age &gt; ?", "Joe", 9).limit(10));
223      * </pre>
224      * This method delegates the call to {@link #find(Class, String, net.java.ao.Query)}, passing the
225      * primary key field for the given type as the <code>String</code> parameter.
226      *
227      * @param type  The type of the entities to retrieve
228      * @param query The {@link net.java.ao.Query} instance to be used to determine the results
229      * @return An array of entities of the given type which match the specified query
230      */
231     <T extends RawEntity<K>, K> T[] find(Class<T> type, Query query);
232 
233     /**
234      * Selects all entities of the specified type which match the given
235      * <code>Query</code>.  This method creates a <code>PreparedStatement</code>
236      * using the <code>Query</code> instance specified against the table
237      * represented by the given type.  This query is then executed (with the
238      * parameters specified in the query).  The method then iterates through
239      * the result set and extracts the specified field, mapping an entity
240      * of the given type to each row.  This array of entities is returned.
241      *
242      * @param type  The type of the entities to retrieve
243      * @param field The field value to use in the creation of the entities.  This is usually
244      *              the primary key field of the corresponding table.
245      * @param query The {@link Query} instance to use in determining the results
246      * @return An array of entities of the given type which match the specified query
247      */
248     <T extends RawEntity<K>, K> T[] find(Class<T> type, String field, Query query);
249 
250     /**
251      * Executes the specified SQL and extracts the given key field, wrapping each
252      * row into a instance of the specified type.  The SQL itself is executed as
253      * a {@link java.sql.PreparedStatement} with the given parameters.
254      * <p>
255      * Example:
256      * <pre>
257      *     manager.findWithSQL(Person.class, "personID", "SELECT personID FROM chairs WHERE position &lt; ? LIMIT ?", 10, 5);
258      * </pre>
259      * The SQL is not parsed or modified in any way by ActiveObjects.  As such, it is
260      * possible to execute database-specific queries using this method without realizing
261      * it.  For example, the above query will not run on MS SQL Server or Oracle, due to
262      * the lack of a LIMIT clause in their SQL implementation.  As such, be extremely
263      * careful about what SQL is executed using this method, or else be conscious of the
264      * fact that you may be locking yourself to a specific DBMS.
265      *
266      * @param type       The type of the entities to retrieve
267      * @param keyField   The field value to use in the creation of the entities. This is usually
268      *                   the primary key field of the corresponding table.
269      * @param sql        The SQL statement to execute.
270      * @param parameters A varargs array of parameters to be passed to the executed
271      *                   prepared statement. The length of this array <i>must</i> match the number of
272      *                   parameters (denoted by the '?' char) in the <code>criteria</code>.
273      * @return An array of entities of the given type which match the specified query
274      */
275     @SuppressWarnings("unchecked")
276     <T extends RawEntity<K>, K> T[] findWithSQL(Class<T> type, String keyField, String sql, Object... parameters);
277 
278     /**
279      * Optimised read for large datasets. This method will stream all rows for the given type to the given callback.
280      * <p>
281      * Please see {@link #stream(Class, Query, EntityStreamCallback)} for details / limitations.
282      *
283      * @param type           The type of the entities to retrieve
284      * @param streamCallback The receiver of the data, will be passed one entity per returned row
285      */
286     <T extends RawEntity<K>, K> void stream(Class<T> type, EntityStreamCallback<T, K> streamCallback);
287 
288     /**
289      * Selects all entities of the given type and feeds them to the callback, one by one. The entities are slim,
290      * uncached, read-only representations of the data. They only supports getters or designated {@link Accessor}
291      * methods. Calling setters or <pre>save</pre> will result in an exception. Other method calls will be ignored.
292      * The proxies do not support lazy-loading of related entities.
293      * <p>
294      * This call is optimised for efficient read operations on large datasets. For best memory usage, do not buffer
295      * the entities passed to the callback but process and discard them directly.
296      *
297      * Unlike regular Entities, the read only implementations do not support flushing/refreshing. The data is a
298      * snapshot view at the time of
299      * query.
300      *
301      * @param type           The type of the entities to retrieve
302      * @param query          The {@link Query} instance to use in determining the results
303      * @param streamCallback The receiver of the data, will be passed one entity per returned row
304      */
305     <T extends RawEntity<K>, K> void stream(Class<T> type, Query query, EntityStreamCallback<T, K> streamCallback);
306 
307     /**
308      * Counts all entities of the specified type. This method is actually
309      * a delegate for: <code>count(Class&lt;? extends Entity&gt;, Query)</code>
310      *
311      * @param type The type of the entities which should be counted.
312      * @return The number of entities of the specified type.
313      */
314     <K> int count(Class<? extends RawEntity<K>> type);
315 
316     /**
317      * Counts all entities of the specified type matching the given criteria
318      * and parameters.  This is a convenience method for:
319      * <code>count(type, Query.select().where(criteria, parameters))</code>
320      *
321      * @param type       The type of the entities which should be counted
322      * @param criteria   A parameterized WHERE statement used to determine the result set which will be counted
323      * @param parameters A varargs array of parameters to be passed to the executed
324      *                   prepared statement.  The length of this array <i>must</i> match the number of
325      *                   parameters (denoted by the '?' char) in the <code>criteria</code>.
326      * @return The number of entities of the given type which match the specified criteria
327      */
328     <K> int count(Class<? extends RawEntity<K>> type, String criteria, Object... parameters);
329 
330     /**
331      * Counts all entities of the specified type matching the given {@link Query}
332      * instance.  The SQL runs as a <code>SELECT COUNT(*)</code> to
333      * ensure maximum performance.
334      *
335      * @param type  The type of the entities which should be counted
336      * @param query The {@link Query} instance used to determine the result set which will be counted
337      * @return The number of entities of the given type which match the specified query
338      */
339     <K> int count(Class<? extends RawEntity<K>> type, Query query);
340 
341     /**
342      * Execute the given callback within a transaction if the host supports transactions,
343      * otherwise executes the callback immediately.
344      *
345      * @param callback the callback to execute within a transaction
346      * @return the result of the transactionCallback
347      */
348     <T> T executeInTransaction(TransactionCallback<T> callback);
349 
350     /**
351      * Provides information about the state of the ActiveObjects module
352      *
353      * @return activeObjectsModuleMetaData
354      * @since 0.24
355      */
356     ActiveObjectsModuleMetaData moduleMetaData();
357 }