001package io.ebean;
002
003import io.avaje.lang.NonNullApi;
004import io.avaje.lang.Nullable;
005import io.ebean.annotation.TxIsolation;
006import io.ebean.cache.ServerCacheManager;
007import io.ebean.plugin.Property;
008import io.ebean.text.csv.CsvReader;
009import io.ebean.text.json.JsonContext;
010
011import javax.persistence.OptimisticLockException;
012import javax.persistence.PersistenceException;
013import java.util.Collection;
014import java.util.List;
015import java.util.Map;
016import java.util.Set;
017import java.util.concurrent.Callable;
018
019/**
020 * DB is a registry of {@link Database} by name.
021 * <p>
022 * DB additionally provides a convenient way to use the 'default' Database.
023 * <p>
024 * <h3>Default database</h3>
025 * <p>
026 * One of the Database instances can be registered as the "default database"
027 * and can be obtained using <code>DB.getDefault()</code>
028 * </p>
029 * <pre>{@code
030 *
031 * Database database = DB.getDefault();
032 *
033 * }</pre>
034 *
035 * <h3>Named database</h3>
036 * <p>
037 * Multiple database instances can be registered with DB and we can obtain them
038 * using <code>DB.byName()</code>
039 * </p>
040 * <pre>{@code
041 *
042 * Database hrDatabase = DB.byName("hr");
043 *
044 * }</pre>
045 *
046 * <h3>Convenience methods</h3>
047 * <p>
048 * DB has methods like {@link #find(Class)} and {@link #save(Object)} which are
049 * just convenience for using the default database.
050 * </p>
051 *
052 * <pre>{@code
053 *
054 * // fetch using the default database
055 * Order order = DB.find(Order.class, 10);
056 *
057 * // is the same as
058 * Database database = DB.getDefault();
059 * Order order = database.find(Order.class, 10);
060 *
061 * }</pre>
062 */
063@NonNullApi
064public final class DB {
065
066  private static final DbContext context = DbContext.getInstance();
067
068  /**
069   * Hide constructor.
070   */
071  private DB() {
072  }
073
074  /**
075   * Backdoor for registering a mock implementation of Database as the default database.
076   */
077  protected static Database mock(String name, Database server, boolean defaultServer) {
078    return context.mock(name, server, defaultServer);
079  }
080
081  /**
082   * Return the default database.
083   */
084  public static Database getDefault() {
085    return context.getDefault();
086  }
087
088  /**
089   * Return the database for the given name.
090   *
091   * @param name The name of the database
092   */
093  public static Database byName(String name) {
094    return context.get(name);
095  }
096
097  /**
098   * Return the ScriptRunner for the default database.
099   * <p>
100   * Useful to run SQL scripts that are resources. For example a test script
101   * for inserting seed data for a particular test.
102   *
103   * <pre>{@code
104   *
105   *   DB.script().run("/scripts/test-script.sql")
106   *
107   * }</pre>
108   */
109  public static ScriptRunner script() {
110    return getDefault().script();
111  }
112
113  /**
114   * Return the ExpressionFactory from the default database.
115   * <p>
116   * The ExpressionFactory is used internally by the query and ExpressionList to
117   * build the WHERE and HAVING clauses. Alternatively you can use the
118   * ExpressionFactory directly to create expressions to add to the query where
119   * clause.
120   * </p>
121   * <p>
122   * Alternatively you can use the {@link Expr} as a shortcut to the
123   * ExpressionFactory of the 'Default' database.
124   * </p>
125   * <p>
126   * You generally need to the an ExpressionFactory (or {@link Expr}) to build
127   * an expression that uses OR like Expression e = Expr.or(..., ...);
128   * </p>
129   */
130  public static ExpressionFactory expressionFactory() {
131    return getDefault().expressionFactory();
132  }
133
134  /**
135   * Deprecated migrate to expressionFactory().
136   */
137  @Deprecated
138  public static ExpressionFactory getExpressionFactory() {
139    return expressionFactory();
140  }
141
142  /**
143   * Return the next identity value for a given bean type.
144   * <p>
145   * This will only work when a IdGenerator is on this bean type such as a DB
146   * sequence or UUID.
147   * </p>
148   * <p>
149   * For DB's supporting getGeneratedKeys and sequences such as Oracle10 you do
150   * not need to use this method generally. It is made available for more
151   * complex cases where it is useful to get an ID prior to some processing.
152   * </p>
153   */
154  public static Object nextId(Class<?> beanType) {
155    return getDefault().nextId(beanType);
156  }
157
158  /**
159   * Start a transaction with 'REQUIRED' semantics.
160   * <p>
161   * With REQUIRED semantics if an active transaction already exists that transaction will be used.
162   * </p>
163   * <p>
164   * The transaction is stored in a ThreadLocal variable and typically you only
165   * need to use the returned Transaction <em>IF</em> you wish to do things like
166   * use batch mode, change the transaction isolation level, use savepoints or
167   * log comments to the transaction log.
168   * </p>
169   * <p>
170   * Example of using a transaction to span multiple calls to find(), save()
171   * etc.
172   * </p>
173   * <pre>{@code
174   *
175   *   try (Transaction transaction = DB.beginTransaction()) {
176   *
177   *     Order order = DB.find(Order.class, 42);
178   *     order.setStatus(Status.COMPLETE);
179   *     order.save();
180   *
181   *     transaction.commit();
182   *   }
183   *
184   * }</pre>
185   * <p>
186   * If we want to externalise the transaction management then we do this via Database.
187   * With Database we can pass the transaction to the various find(), save() and execute()
188   * methods. This gives us the ability to create the transactions externally from Ebean
189   * and use the transaction explicitly via the various methods available on Database.
190   * </p>
191   */
192  public static Transaction beginTransaction() {
193    return getDefault().beginTransaction();
194  }
195
196  /**
197   * Create a new transaction that is not held in TransactionThreadLocal.
198   * <p>
199   * You will want to do this if you want multiple Transactions in a single
200   * thread or generally use transactions outside of the TransactionThreadLocal
201   * management.
202   * </p>
203   */
204  public static Transaction createTransaction() {
205    return getDefault().createTransaction();
206  }
207
208  /**
209   * Start a transaction additionally specifying the isolation level.
210   *
211   * @param isolation the Transaction isolation level
212   */
213  public static Transaction beginTransaction(TxIsolation isolation) {
214    return getDefault().beginTransaction(isolation);
215  }
216
217  /**
218   * Start a transaction typically specifying REQUIRES_NEW or REQUIRED semantics.
219   * <p>
220   * Note that this provides an try finally alternative to using {@link #executeCall(TxScope, Callable)} or
221   * {@link #execute(TxScope, Runnable)}.
222   * </p>
223   * <p>
224   * <h3>REQUIRES_NEW example:</h3>
225   * <pre>{@code
226   * // Start a new transaction. If there is a current transaction
227   * // suspend it until this transaction ends
228   *
229   * try (Transaction txn = DB.beginTransaction(TxScope.requiresNew())) {
230   *   ...
231   *
232   *   // commit the transaction
233   *   txn.commit();
234   * }
235   * }</pre>
236   *
237   * <h3>REQUIRED example:</h3>
238   * <pre>{@code
239   * // start a new transaction if there is not a current transaction
240   *
241   * try (Transaction txn = DB.beginTransaction(TxScope.required())) {
242   *   ...
243   *
244   *   // commit the transaction if it was created or
245   *   // do nothing if there was already a current transaction
246   *   txn.commit();
247   * }
248   * }</pre>
249   */
250  public static Transaction beginTransaction(TxScope scope) {
251    return getDefault().beginTransaction(scope);
252  }
253
254  /**
255   * Returns the current transaction or null if there is no current transaction in scope.
256   */
257  public static Transaction currentTransaction() {
258    return getDefault().currentTransaction();
259  }
260
261  /**
262   * The batch will be flushing automatically but you can use this to explicitly
263   * flush the batch if you like.
264   * <p>
265   * Flushing occurs automatically when:
266   * </p>
267   * <ul>
268   * <li>the batch size is reached</li>
269   * <li>A query is executed on the same transaction</li>
270   * <li>UpdateSql or CallableSql are mixed with bean save and delete</li>
271   * <li>Transaction commit occurs</li>
272   * <li>A getter method is called on a batched bean</li>
273   * </ul>
274   */
275  public static void flush() {
276    currentTransaction().flush();
277  }
278
279  /**
280   * Register a TransactionCallback on the currently active transaction.
281   * <p/>
282   * If there is no currently active transaction then a PersistenceException is thrown.
283   *
284   * @param transactionCallback the transaction callback to be registered with the current transaction
285   * @throws PersistenceException if there is no currently active transaction
286   */
287  public static void register(TransactionCallback transactionCallback) throws PersistenceException {
288    getDefault().register(transactionCallback);
289  }
290
291  /**
292   * Commit the current transaction.
293   */
294  public static void commitTransaction() {
295    getDefault().commitTransaction();
296  }
297
298  /**
299   * Rollback the current transaction.
300   */
301  public static void rollbackTransaction() {
302    getDefault().rollbackTransaction();
303  }
304
305  /**
306   * If the current transaction has already been committed do nothing otherwise
307   * rollback the transaction.
308   * <p>
309   * It is preferable to use <em>try with resources</em> rather than this.
310   * </p>
311   * <p>
312   * Useful to put in a finally block to ensure the transaction is ended, rather
313   * than a rollbackTransaction() in each catch block.
314   * </p>
315   * <p>
316   * Code example:
317   * </p>
318   * <pre>{@code
319   *   DB.beginTransaction();
320   *   try {
321   *     // do some fetching and or persisting
322   *
323   *     // commit at the end
324   *     DB.commitTransaction();
325   *
326   *   } finally {
327   *     // if commit didn't occur then rollback the transaction
328   *     DB.endTransaction();
329   *   }
330   * }</pre>
331   */
332  public static void endTransaction() {
333    getDefault().endTransaction();
334  }
335
336  /**
337   * Mark the current transaction as rollback only.
338   */
339  public static void setRollbackOnly() {
340    getDefault().currentTransaction().setRollbackOnly();
341  }
342
343  /**
344   * Return a map of the differences between two objects of the same type.
345   * <p>
346   * When null is passed in for b, then the 'OldValues' of a is used for the
347   * difference comparison.
348   * </p>
349   */
350  public static Map<String, ValuePair> diff(Object a, Object b) {
351    return getDefault().diff(a, b);
352  }
353
354  /**
355   * Either Insert or Update the bean depending on its state.
356   * <p>
357   * If there is no current transaction one will be created and committed for
358   * you automatically.
359   * </p>
360   * <p>
361   * Save can cascade along relationships. For this to happen you need to
362   * specify a cascade of CascadeType.ALL or CascadeType.PERSIST on the
363   * OneToMany, OneToOne or ManyToMany annotation.
364   * </p>
365   * <p>
366   * When a save cascades via a OneToMany or ManyToMany Ebean will automatically
367   * set the 'parent' object to the 'detail' object. In the example below in
368   * saving the order and cascade saving the order details the 'parent' order
369   * will be set against each order detail when it is saved.
370   * </p>
371   */
372  public static void save(Object bean) throws OptimisticLockException {
373    getDefault().save(bean);
374  }
375
376  /**
377   * Insert the bean. This is useful when you set the Id property on a bean and
378   * want to explicitly insert it.
379   */
380  public static void insert(Object bean) {
381    getDefault().insert(bean);
382  }
383
384  /**
385   * Insert a collection of beans.
386   */
387  public static void insertAll(Collection<?> beans) {
388    getDefault().insertAll(beans);
389  }
390
391  /**
392   * Marks the entity bean as dirty.
393   * <p>
394   * This is used so that when a bean that is otherwise unmodified is updated with the version
395   * property updated.
396   * <p>
397   * An unmodified bean that is saved or updated is normally skipped and this marks the bean as
398   * dirty so that it is not skipped.
399   * <pre>{@code
400   *
401   *   Customer customer = DB.find(Customer, id);
402   *
403   *   // mark the bean as dirty so that a save() or update() will
404   *   // increment the version property
405   *   DB.markAsDirty(customer);
406   *   DB.save(customer);
407   *
408   * }</pre>
409   */
410  public static void markAsDirty(Object bean) throws OptimisticLockException {
411    getDefault().markAsDirty(bean);
412  }
413
414  /**
415   * Saves the bean using an update. If you know you are updating a bean then it is preferrable to
416   * use this update() method rather than save().
417   * <p>
418   * <b>Stateless updates:</b> Note that the bean does not have to be previously fetched to call
419   * update().You can create a new instance and set some of its properties programmatically for via
420   * JSON/XML marshalling etc. This is described as a 'stateless update'.
421   * </p>
422   * <p>
423   * <b>Optimistic Locking: </b> Note that if the version property is not set when update() is
424   * called then no optimistic locking is performed (internally ConcurrencyMode.NONE is used).
425   * </p>
426   * <p>
427   * <pre>{@code
428   *
429   *   // A 'stateless update' example
430   *   Customer customer = new Customer();
431   *   customer.setId(7);
432   *   customer.setName("ModifiedNameNoOCC");
433   *   database.update(customer);
434   *
435   * }</pre>
436   */
437  public static void update(Object bean) throws OptimisticLockException {
438    getDefault().update(bean);
439  }
440
441  /**
442   * Update the beans in the collection.
443   */
444  public static void updateAll(Collection<?> beans) throws OptimisticLockException {
445    getDefault().updateAll(beans);
446  }
447
448  /**
449   * Merge the bean using the default merge options.
450   *
451   * @param bean The bean to merge
452   */
453  public static void merge(Object bean) {
454    getDefault().merge(bean);
455  }
456
457  /**
458   * Merge the bean using the given merge options.
459   *
460   * @param bean    The bean to merge
461   * @param options The options to control the merge
462   */
463  public static void merge(Object bean, MergeOptions options) {
464    getDefault().merge(bean, options);
465  }
466
467  /**
468   * Save all the beans from a Collection.
469   */
470  public static int saveAll(Collection<?> beans) throws OptimisticLockException {
471    return getDefault().saveAll(beans);
472  }
473
474  /**
475   * Save all the beans from a Collection.
476   */
477  public static int saveAll(Object... beans) throws OptimisticLockException {
478    return getDefault().saveAll(beans);
479  }
480
481  /**
482   * This method checks the uniqueness of a bean. I.e. if the save will work. It will return the
483   * properties that violates an unique / primary key. This may be done in an UI save action to
484   * validate if the user has entered correct values.
485   * <p>
486   * Note: This method queries the DB for uniqueness of all indices, so do not use it in a batch update.
487   * <p>
488   * Note: This checks only the root bean!
489   * <p>
490   * <pre>{@code
491   *
492   *   // there is a unique constraint on title
493   *
494   *   Document doc = new Document();
495   *   doc.setTitle("One flew over the cuckoo's nest");
496   *   doc.setBody("clashes with doc1");
497   *
498   *   Set<Property> properties = DB.checkUniqueness(doc);
499   *
500   *   if (properties.isEmpty()) {
501   *     // it is unique ... carry on
502   *
503   *   } else {
504   *     // build a user friendly message
505   *     // to return message back to user
506   *
507   *     String uniqueProperties = properties.toString();
508   *
509   *     StringBuilder msg = new StringBuilder();
510   *
511   *     properties.forEach((it)-> {
512   *       Object propertyValue = it.getVal(doc);
513   *       String propertyName = it.getName();
514   *       msg.append(" property["+propertyName+"] value["+propertyValue+"]");
515   *     });
516   *
517   *     // uniqueProperties > [title]
518   *     //       custom msg > property[title] value[One flew over the cuckoo's nest]
519   *
520   *  }
521   *
522   * }</pre>
523   *
524   * @param bean The entity bean to check uniqueness on
525   * @return a set of Properties if constraint validation was detected or empty list.
526   */
527  public static Set<Property> checkUniqueness(Object bean) {
528    return getDefault().checkUniqueness(bean);
529  }
530
531  /**
532   * Same as {@link #checkUniqueness(Object)} but with given transaction.
533   */
534  public static Set<Property> checkUniqueness(Object bean, Transaction transaction) {
535    return getDefault().checkUniqueness(bean, transaction);
536  }
537
538  /**
539   * Delete the bean.
540   * <p>
541   * This will return true if the bean was deleted successfully or JDBC batch is being used.
542   * </p>
543   * <p>
544   * If there is no current transaction one will be created and committed for
545   * you automatically.
546   * </p>
547   * <p>
548   * If the bean is configured with <code>@SoftDelete</code> then this will perform a soft
549   * delete rather than a hard/permanent delete.
550   * </p>
551   * <p>
552   * If the Bean does not have a version property (or loaded version property) and
553   * the bean does not exist then this returns false indicating that nothing was
554   * deleted. Note that, if JDBC batch mode is used then this always returns true.
555   * </p>
556   */
557  public static boolean delete(Object bean) throws OptimisticLockException {
558    return getDefault().delete(bean);
559  }
560
561  /**
562   * Delete the bean in permanent fashion (will not use soft delete).
563   */
564  public static boolean deletePermanent(Object bean) throws OptimisticLockException {
565    return getDefault().deletePermanent(bean);
566  }
567
568  /**
569   * Delete the bean given its type and id.
570   */
571  public static int delete(Class<?> beanType, Object id) {
572    return getDefault().delete(beanType, id);
573  }
574
575  /**
576   * Delete permanent the bean given its type and id.
577   */
578  public static int deletePermanent(Class<?> beanType, Object id) {
579    return getDefault().deletePermanent(beanType, id);
580  }
581
582  /**
583   * Delete several beans given their type and id values.
584   */
585  public static int deleteAll(Class<?> beanType, Collection<?> ids) {
586    return getDefault().deleteAll(beanType, ids);
587  }
588
589  /**
590   * Delete permanent several beans given their type and id values.
591   */
592  public static int deleteAllPermanent(Class<?> beanType, Collection<?> ids) {
593    return getDefault().deleteAllPermanent(beanType, ids);
594  }
595
596  /**
597   * Delete all the beans in the Collection.
598   */
599  public static int deleteAll(Collection<?> beans) throws OptimisticLockException {
600    return getDefault().deleteAll(beans);
601  }
602
603  /**
604   * Delete permanent all the beans in the Collection (will not use soft delete).
605   */
606  public static int deleteAllPermanent(Collection<?> beans) throws OptimisticLockException {
607    return getDefault().deleteAllPermanent(beans);
608  }
609
610  /**
611   * Refresh the values of a bean.
612   * <p>
613   * Note that this resets OneToMany and ManyToMany properties so that if they
614   * are accessed a lazy load will refresh the many property.
615   * </p>
616   */
617  public static void refresh(Object bean) {
618    getDefault().refresh(bean);
619  }
620
621  /**
622   * Refresh a 'many' property of a bean.
623   * <pre>{@code
624   *
625   *   Order order = ...;
626   *   ...
627   *   // refresh the order details...
628   *   DB.refreshMany(order, "details");
629   *
630   * }</pre>
631   *
632   * @param bean             the entity bean containing the List Set or Map to refresh.
633   * @param manyPropertyName the property name of the List Set or Map to refresh.
634   */
635  public static void refreshMany(Object bean, String manyPropertyName) {
636    getDefault().refreshMany(bean, manyPropertyName);
637  }
638
639  /**
640   * Get a reference object.
641   * <p>
642   * This is sometimes described as a proxy (with lazy loading).
643   * </p>
644   * <pre>{@code
645   *
646   *   Product product = DB.getReference(Product.class, 1);
647   *
648   *   // You can get the id without causing a fetch/lazy load
649   *   Integer productId = product.getId();
650   *
651   *   // If you try to get any other property a fetch/lazy loading will occur
652   *   // This will cause a query to execute...
653   *   String name = product.getName();
654   *
655   * }</pre>
656   *
657   * @param beanType the type of entity bean
658   * @param id       the id value
659   */
660  public static <T> T reference(Class<T> beanType, Object id) {
661    return getDefault().reference(beanType, id);
662  }
663
664  /**
665   * Deprecated migrate to beanId().
666   */
667  @Deprecated
668  public static <T> T getReference(Class<T> beanType, Object id) {
669    return reference(beanType, id);
670  }
671
672  /**
673   * Sort the list using the sortByClause which can contain a comma delimited
674   * list of property names and keywords asc, desc, nullsHigh and nullsLow.
675   * <ul>
676   * <li>asc - ascending order (which is the default)</li>
677   * <li>desc - Descending order</li>
678   * <li>nullsHigh - Treat null values as high/large values (which is the default)</li>
679   * <li>nullsLow- Treat null values as low/very small values</li>
680   * </ul>
681   * <p>
682   * If you leave off any keywords the defaults are ascending order and treating
683   * nulls as high values.
684   * <p>
685   * Note that the sorting uses a Comparator and Collections.sort(); and does
686   * not invoke a DB query.
687   * </p>
688   * <pre>{@code
689   *
690   *   // find orders and their customers
691   *   List<Order> list = DB.find(Order.class)
692   *     .fetch("customer")
693   *     .order("id")
694   *     .findList();
695   *
696   *   // sort by customer name ascending, then by order shipDate
697   *   // ... then by the order status descending
698   *   DB.sort(list, "customer.name, shipDate, status desc");
699   *
700   *   // sort by customer name descending (with nulls low)
701   *   // ... then by the order id
702   *   DB.sort(list, "customer.name desc nullsLow, id");
703   *
704   * }</pre>
705   *
706   * @param list         the list of entity beans
707   * @param sortByClause the properties to sort the list by
708   */
709  public static <T> void sort(List<T> list, String sortByClause) {
710    getDefault().sort(list, sortByClause);
711  }
712
713  /**
714   * Find a bean using its unique id. This will not use caching.
715   * <pre>{@code
716   *
717   *   // Fetch order 1
718   *   Order order = DB.find(Order.class, 1);
719   *
720   * }</pre>
721   * <p>
722   * If you want more control over the query then you can use createQuery() and
723   * Query.findOne();
724   * </p>
725   * <pre>{@code
726   *
727   *   // ... additionally fetching customer, customer shipping address,
728   *   // order details, and the product associated with each order detail.
729   *   // note: only product id and name is fetch (its a "partial object").
730   *   // note: all other objects use "*" and have all their properties fetched.
731   *
732   *   Query<Order> query = DB.find(Order.class)
733   *     .setId(1)
734   *     .fetch("customer")
735   *     .fetch("customer.shippingAddress")
736   *     .fetch("details")
737   *     .query();
738   *
739   *   // fetch associated products but only fetch their product id and name
740   *   query.fetch("details.product", "name");
741   *
742   *   // traverse the object graph...
743   *
744   *   Order order = query.findOne();
745   *
746   *   Customer customer = order.getCustomer();
747   *   Address shippingAddress = customer.getShippingAddress();
748   *   List<OrderDetail> details = order.getDetails();
749   *   OrderDetail detail0 = details.get(0);
750   *   Product product = detail0.getProduct();
751   *   String productName = product.getName();
752   *
753   * }</pre>
754   *
755   * @param beanType the type of entity bean to fetch
756   * @param id       the id value
757   */
758  @Nullable
759  public static <T> T find(Class<T> beanType, Object id) {
760    return getDefault().find(beanType, id);
761  }
762
763  /**
764   * Look to execute a native sql query that does not returns beans but instead
765   * returns SqlRow or direct access to ResultSet (see {@link SqlQuery#findList(RowMapper)}.
766   *
767   * <p>
768   * Refer to {@link DtoQuery} for native sql queries returning DTO beans.
769   * </p>
770   * <p>
771   * Refer to {@link #findNative(Class, String)} for native sql queries returning entity beans.
772   * </p>
773   */
774  public static SqlQuery sqlQuery(String sql) {
775    return getDefault().sqlQuery(sql);
776  }
777
778  /**
779   * Deprecated - migrate to sqlQuery().
780   * <p>
781   * This is an alias for {@link #sqlQuery(String)}.
782   */
783  @Deprecated
784  public static SqlQuery createSqlQuery(String sql) {
785    return sqlQuery(sql);
786  }
787
788  /**
789   * Look to execute a native sql insert update or delete statement.
790   * <p>
791   * Use this to execute a Insert Update or Delete statement. The statement will
792   * be native to the database and contain database table and column names.
793   * </p>
794   *
795   * <p>
796   * See {@link SqlUpdate} for example usage.
797   * </p>
798   *
799   * @return The SqlUpdate instance to set parameters and execute
800   */
801  public static SqlUpdate sqlUpdate(String sql) {
802    return getDefault().sqlUpdate(sql);
803  }
804
805  /**
806   * Deprecated - migrate to sqlUpdate().
807   * <p>
808   * This is an alias for {@link #sqlUpdate(String)}.
809   */
810  @Deprecated
811  public static SqlUpdate createSqlUpdate(String sql) {
812    return sqlUpdate(sql);
813  }
814
815  /**
816   * Create a CallableSql to execute a given stored procedure.
817   *
818   * @see CallableSql
819   */
820  public static CallableSql createCallableSql(String sql) {
821    return getDefault().createCallableSql(sql);
822  }
823
824  /**
825   * Create a orm update where you will supply the insert/update or delete
826   * statement (rather than using a named one that is already defined using the
827   * &#064;NamedUpdates annotation).
828   * <p>
829   * The orm update differs from the sql update in that it you can use the bean
830   * name and bean property names rather than table and column names.
831   * </p>
832   * <p>
833   * An example:
834   * </p>
835   * <pre>{@code
836   *
837   *   // The bean name and properties - "topic","postCount" and "id"
838   *
839   *   // will be converted into their associated table and column names
840   *   String updStatement = "update topic set postCount = :pc where id = :id";
841   *
842   *   Update<Topic> update = DB.createUpdate(Topic.class, updStatement);
843   *
844   *   update.set("pc", 9);
845   *   update.set("id", 3);
846   *
847   *   int rows = update.execute();
848   *   System.out.println("rows updated:" + rows);
849   *
850   * }</pre>
851   */
852  public static <T> Update<T> createUpdate(Class<T> beanType, String ormUpdate) {
853    return getDefault().createUpdate(beanType, ormUpdate);
854  }
855
856  /**
857   * Create a CsvReader for a given beanType.
858   */
859  public static <T> CsvReader<T> createCsvReader(Class<T> beanType) {
860    return getDefault().createCsvReader(beanType);
861  }
862
863  /**
864   * Create a named query.
865   * <p>
866   * For RawSql the named query is expected to be in ebean.xml.
867   * </p>
868   *
869   * @param beanType   The type of entity bean
870   * @param namedQuery The name of the query
871   * @param <T>        The type of entity bean
872   * @return The query
873   */
874  public static <T> Query<T> createNamedQuery(Class<T> beanType, String namedQuery) {
875    return getDefault().createNamedQuery(beanType, namedQuery);
876  }
877
878  /**
879   * Create a query for a type of entity bean.
880   * <p>
881   * You can use the methods on the Query object to specify fetch paths,
882   * predicates, order by, limits etc.
883   * </p>
884   * <p>
885   * You then use findList(), findSet(), findMap() and findOne() to execute
886   * the query and return the collection or bean.
887   * </p>
888   * <p>
889   * Note that a query executed by {@link Query#findList()} etc will execute against
890   * the same database from which is was created.
891   * </p>
892   *
893   * @param beanType the class of entity to be fetched
894   * @return A ORM Query for this beanType
895   */
896  public static <T> Query<T> createQuery(Class<T> beanType) {
897    return getDefault().createQuery(beanType);
898  }
899
900  /**
901   * Parse the Ebean query language statement returning the query which can then
902   * be modified (add expressions, change order by clause, change maxRows, change
903   * fetch and select paths etc).
904   * <p>
905   * <h3>Example</h3>
906   * <pre>{@code
907   *
908   *   // Find order additionally fetching the customer, details and details.product name.
909   *
910   *   String eql = "fetch customer fetch details fetch details.product (name) where id = :orderId ";
911   *
912   *   Query<Order> query = DB.createQuery(Order.class, eql);
913   *   query.setParameter("orderId", 2);
914   *
915   *   Order order = query.findOne();
916   *
917   *   // This is the same as:
918   *
919   *   Order order = DB.find(Order.class)
920   *     .fetch("customer")
921   *     .fetch("details")
922   *     .fetch("detail.product", "name")
923   *     .setId(2)
924   *     .findOne();
925   *
926   * }</pre>
927   *
928   * @param beanType The type of bean to fetch
929   * @param eql      The Ebean query
930   * @param <T>      The type of the entity bean
931   * @return The query with expressions defined as per the parsed query statement
932   */
933  public static <T> Query<T> createQuery(Class<T> beanType, String eql) {
934    return getDefault().createQuery(beanType, eql);
935  }
936
937  /**
938   * Create a query for a type of entity bean.
939   * <p>
940   * This is actually the same as {@link #createQuery(Class)}. The reason it
941   * exists is that people used to JPA will probably be looking for a
942   * createQuery method (the same as entityManager).
943   * </p>
944   *
945   * @param beanType the type of entity bean to find
946   * @return A ORM Query object for this beanType
947   */
948  public static <T> Query<T> find(Class<T> beanType) {
949    return getDefault().find(beanType);
950  }
951
952  /**
953   * Create a query using native SQL.
954   * <p>
955   * The native SQL can contain named parameters or positioned parameters.
956   * </p>
957   * <pre>{@code
958   *
959   *   String sql = "select c.id, c.name from customer c where c.name like ? order by c.name";
960   *
961   *   Query<Customer> query = database.findNative(Customer.class, sql);
962   *   query.setParameter(1, "Rob%");
963   *
964   *   List<Customer> customers = query.findList();
965   *
966   * }</pre>
967   *
968   * @param beanType  The type of entity bean to fetch
969   * @param nativeSql The SQL that can contain named or positioned parameters
970   * @return The query to set parameters and execute
971   */
972  public static <T> Query<T> findNative(Class<T> beanType, String nativeSql) {
973    return getDefault().findNative(beanType, nativeSql);
974  }
975
976  /**
977   * Create a Query for DTO beans.
978   * <p>
979   * DTO beans are just normal bean like classes with public constructor(s) and setters.
980   * They do not need to be registered with Ebean before use.
981   * </p>
982   *
983   * @param dtoType The type of the DTO bean the rows will be mapped into.
984   * @param sql     The SQL query to execute.
985   * @param <T>     The type of the DTO bean.
986   */
987  public static <T> DtoQuery<T> findDto(Class<T> dtoType, String sql) {
988    return getDefault().findDto(dtoType, sql);
989  }
990
991  /**
992   * Create an Update query to perform a bulk update.
993   * <p>
994   * <pre>{@code
995   *
996   *  int rows = DB.update(Customer.class)
997   *      .set("status", Customer.Status.ACTIVE)
998   *      .set("updtime", new Timestamp(System.currentTimeMillis()))
999   *      .where()
1000   *        .gt("id", 1000)
1001   *        .update();
1002   *
1003   * }</pre>
1004   *
1005   * @param beanType The type of entity bean to update
1006   * @param <T>      The type of entity bean
1007   * @return The update query to use
1008   */
1009  public static <T> UpdateQuery<T> update(Class<T> beanType) {
1010    return getDefault().update(beanType);
1011  }
1012
1013  /**
1014   * Create a filter for sorting and filtering lists of entities locally without
1015   * going back to the database.
1016   * <p>
1017   * This produces and returns a new list with the sort and filters applied.
1018   * </p>
1019   * <p>
1020   * Refer to {@link Filter} for an example of its use.
1021   * </p>
1022   */
1023  public static <T> Filter<T> filter(Class<T> beanType) {
1024    return getDefault().filter(beanType);
1025  }
1026
1027  /**
1028   * Execute a TxRunnable in a Transaction with an explicit scope.
1029   * <p>
1030   * The scope can control the transaction type, isolation and rollback
1031   * semantics.
1032   * </p>
1033   * <pre>{@code
1034   *
1035   * // set specific transactional scope settings
1036   * TxScope scope = TxScope.requiresNew().setIsolation(TxIsolation.SERIALIZABLE);
1037   *
1038   * DB.execute(scope, new TxRunnable() {
1039   *   public void run() {
1040   *       User u1 = DB.find(User.class, 1);
1041   *     ...
1042   *   }
1043   * });
1044   *
1045   * }</pre>
1046   */
1047  public static void execute(TxScope scope, Runnable r) {
1048    getDefault().execute(scope, r);
1049  }
1050
1051  /**
1052   * Execute a Runnable in a Transaction with the default scope.
1053   * <p>
1054   * The default scope runs with REQUIRED and by default will rollback on any
1055   * exception (checked or runtime).
1056   * </p>
1057   * <pre>{@code
1058   *
1059   * DB.execute(() -> {
1060   *
1061   *   User u1 = DB.find(User.class, 1);
1062   *   User u2 = DB.find(User.class, 2);
1063   *
1064   *   u1.setName("u1 mod");
1065   *   u2.setName("u2 mod");
1066   *
1067   *   DB.save(u1);
1068   *   DB.save(u2);
1069   * });
1070   * }</pre>
1071   */
1072  public static void execute(Runnable r) {
1073    getDefault().execute(r);
1074  }
1075
1076  /**
1077   * Execute a Callable in a Transaction with an explicit scope.
1078   * <p>
1079   * The scope can control the transaction type, isolation and rollback
1080   * semantics.
1081   * </p>
1082   * <pre>{@code
1083   *
1084   * // set specific transactional scope settings
1085   * TxScope scope = TxScope.requiresNew().setIsolation(TxIsolation.SERIALIZABLE);
1086   *
1087   * DB.executeCall(scope, new Callable<String>() {
1088   *   public String call() {
1089   *       User u1 = DB.find(User.class, 1);
1090   *             ...
1091   *             return u1.getEmail();
1092   *   }
1093   * });
1094   * }</pre>
1095   */
1096  public static <T> T executeCall(TxScope scope, Callable<T> c) {
1097    return getDefault().executeCall(scope, c);
1098  }
1099
1100  /**
1101   * Execute a Callable in a Transaction with the default scope.
1102   * <p>
1103   * The default scope runs with REQUIRED and by default will rollback on any
1104   * exception (checked or runtime).
1105   * </p>
1106   * <p>
1107   * This is basically the same as TxRunnable except that it returns an Object
1108   * (and you specify the return type via generics).
1109   * </p>
1110   * <pre>{@code
1111   *
1112   * DB.executeCall(() -> {
1113   *
1114   *   User u1 = DB.find(User.class, 1);
1115   *   User u2 = DB.find(User.class, 2);
1116   *
1117   *   u1.setName("u1 mod");
1118   *   u2.setName("u2 mod");
1119   *
1120   *   DB.save(u1);
1121   *   DB.save(u2);
1122   *
1123   *   return u1.getEmail();
1124   * });
1125   * }</pre>
1126   */
1127  public static <T> T executeCall(Callable<T> c) {
1128    return getDefault().executeCall(c);
1129  }
1130
1131  /**
1132   * Inform Ebean that tables have been modified externally. These could be the
1133   * result of from calling a stored procedure, other JDBC calls or external
1134   * programs including other frameworks.
1135   * <p>
1136   * If you use DB.execute(UpdateSql) then the table modification information
1137   * is automatically deduced and you do not need to call this method yourself.
1138   * </p>
1139   * <p>
1140   * This information is used to invalidate objects out of the cache and
1141   * potentially text indexes. This information is also automatically broadcast
1142   * across the cluster.
1143   * </p>
1144   * <p>
1145   * If there is a transaction then this information is placed into the current
1146   * transactions event information. When the transaction is committed this
1147   * information is registered (with the transaction manager). If this
1148   * transaction is rolled back then none of the transaction event information
1149   * registers including the information you put in via this method.
1150   * </p>
1151   * <p>
1152   * If there is NO current transaction when you call this method then this
1153   * information is registered immediately (with the transaction manager).
1154   * </p>
1155   *
1156   * @param tableName the name of the table that was modified
1157   * @param inserts   true if rows where inserted into the table
1158   * @param updates   true if rows on the table where updated
1159   * @param deletes   true if rows on the table where deleted
1160   */
1161  public static void externalModification(String tableName, boolean inserts, boolean updates, boolean deletes) {
1162    getDefault().externalModification(tableName, inserts, updates, deletes);
1163  }
1164
1165  /**
1166   * Return the BeanState for a given entity bean.
1167   * <p>
1168   * This will return null if the bean is not an enhanced entity bean.
1169   * </p>
1170   */
1171  public static BeanState beanState(Object bean) {
1172    return getDefault().beanState(bean);
1173  }
1174
1175  /**
1176   * Deprecated migrate to beanState().
1177   */
1178  @Deprecated
1179  public static BeanState getBeanState(Object bean) {
1180    return beanState(bean);
1181  }
1182
1183  /**
1184   * Return the value of the Id property for a given bean.
1185   */
1186  public static Object beanId(Object bean) {
1187    return getDefault().beanId(bean);
1188  }
1189
1190  /**
1191   * Deprecated migrate to beanId().
1192   */
1193  @Deprecated
1194  public static Object getBeanId(Object bean) {
1195    return beanId(bean);
1196  }
1197
1198  /**
1199   * Load and lock the bean using {@code select for update}.
1200   * <p>
1201   * This should be executed inside a transaction.
1202   * <p>
1203   * The bean needs to have an ID property set and can be a reference bean (only has ID)
1204   * or partially or fully populated bean. This will load all the properties of the bean
1205   * from the database using {@code select for update}.
1206   *
1207   * @param bean The entity bean that we wish to obtain a database lock on.
1208   */
1209  public static void lock(Object bean) {
1210    getDefault().lock(bean);
1211  }
1212
1213  /**
1214   * Deprecated migrate to cacheManager().
1215   */
1216  @Deprecated
1217  public static ServerCacheManager getServerCacheManager() {
1218    return getDefault().cacheManager();
1219  }
1220
1221  /**
1222   * Return the manager of the level 2 cache ("L2" cache).
1223   */
1224  public static ServerCacheManager cacheManager() {
1225    return getDefault().cacheManager();
1226  }
1227
1228  /**
1229   * Return the BackgroundExecutor service for asynchronous processing of
1230   * queries.
1231   */
1232  public static BackgroundExecutor backgroundExecutor() {
1233    return getDefault().backgroundExecutor();
1234  }
1235
1236  /**
1237   * Deprecated migrate to backgroundExecutor().
1238   */
1239  @Deprecated
1240  public static BackgroundExecutor getBackgroundExecutor() {
1241    return backgroundExecutor();
1242  }
1243
1244  /**
1245   * Return the JsonContext for reading/writing JSON.
1246   */
1247  public static JsonContext json() {
1248    return getDefault().json();
1249  }
1250
1251  /**
1252   * Truncate the base tables for the given bean types.
1253   */
1254  public static void truncate(Class<?>... types) {
1255    getDefault().truncate(types);
1256  }
1257
1258  /**
1259   * Truncate the given tables.
1260   */
1261  public static void truncate(String... tables) {
1262    getDefault().truncate(tables);
1263  }
1264
1265}