1 package com.xtremelabs.robolectric.util;
2 
3 import java.lang.annotation.ElementType;
4 import java.lang.annotation.Inherited;
5 import java.lang.annotation.Retention;
6 import java.lang.annotation.RetentionPolicy;
7 import java.lang.annotation.Target;
8 import java.sql.Connection;
9 import java.sql.DriverManager;
10 import java.sql.SQLException;
11 
12 
13 public class DatabaseConfig {
14     private static DatabaseMap dbMap = null;
15     private static boolean isLoaded = false;
16 
setDatabaseMap(DatabaseMap map)17     public static void setDatabaseMap(DatabaseMap map) {
18         dbMap = map;
19         isLoaded = false; //make sure to reset isLoaded or mixing databases in a test suite will fail.
20     }
21 
getDatabaseMap()22     public static DatabaseMap getDatabaseMap() {
23         return dbMap;
24     }
25 
26     /**
27      * check if the map has been loaded
28      *
29      * @return
30      */
isMapLoaded()31     public static boolean isMapLoaded() {
32         return isLoaded;
33     }
34 
35     /**
36      * Check if the map has been set at all.
37      *
38      * @return
39      */
isMapNull()40     public static boolean isMapNull() {
41         return dbMap == null;
42     }
43 
44     /**
45      * Sets what database will be used and loads the database driver, based on what DBmap is provided.
46      */
LoadSQLiteDriver()47     private static void LoadSQLiteDriver() {
48         if (isMapNull()) throw new NullDatabaseMapException("Error in DatabaseConfig: DatabaseMap has not been set.");
49         try {
50             Class.forName(dbMap.getDriverClassName()).newInstance();
51         } catch (InstantiationException e) {
52             throw new CannotLoadDatabaseMapDriverException("Error in DatabaseConfig: SQLite driver could not be instantiated;", e);
53         } catch (IllegalAccessException e) {
54             throw new CannotLoadDatabaseMapDriverException("Error in DatabaseConfig: SQLite driver could not be accessed;", e);
55         } catch (ClassNotFoundException e) {
56             throw new CannotLoadDatabaseMapDriverException("Error in DatabaseConfig: SQLite driver class could not be found;", e);
57         }
58         isLoaded = true;
59     }
60 
61     /**
62      * Gets an in memory DB connection.  Will load DB Driver if not already loaded.
63      *
64      * @return Connection to In Memory Database.
65      */
getMemoryConnection()66     public static Connection getMemoryConnection() {
67         if (!isMapLoaded()) LoadSQLiteDriver();
68         try {
69             return DriverManager.getConnection(dbMap.getConnectionString());
70         } catch (SQLException e) {
71             throw new CannotLoadDatabaseMapDriverException("Error in DatabaseConfig, could not retrieve connection to in memory database.", e);
72         }
73     }
74 
75     /**
76      * Makes any edits necessary in the SQL string for it to be compatible with the database in use.
77      *
78      * @return
79      * @throws SQLException
80      */
getScrubSQL(String sql)81     public static String getScrubSQL(String sql) throws SQLException {
82         if (isMapNull()) throw new NullDatabaseMapException("No database map set!");
83         return dbMap.getScrubSQL(sql);
84     }
85 
getSelectLastInsertIdentity()86     public static String getSelectLastInsertIdentity() {
87         if (isMapNull()) throw new NullDatabaseMapException("No database map set!");
88         return dbMap.getSelectLastInsertIdentity();
89     }
90 
getResultSetType()91     public static int getResultSetType() {
92         if (isMapNull()) throw new NullDatabaseMapException("No database map set!");
93         return dbMap.getResultSetType();
94     }
95 
96     public interface DatabaseMap {
getDriverClassName()97         String getDriverClassName();
98 
getConnectionString()99         String getConnectionString();
100 
getScrubSQL(String sql)101         String getScrubSQL(String sql) throws SQLException;
102 
getSelectLastInsertIdentity()103         String getSelectLastInsertIdentity();
104 
getResultSetType()105         int getResultSetType();
106     }
107 
108     public static class NullDatabaseMapException extends RuntimeException {
109         private static final long serialVersionUID = -4580960157495617424L;
110 
NullDatabaseMapException(String message)111         public NullDatabaseMapException(String message) {
112             super(message);
113         }
114     }
115 
116     public static class CannotLoadDatabaseMapDriverException extends RuntimeException {
117         private static final long serialVersionUID = 2614876121296128364L;
118 
CannotLoadDatabaseMapDriverException(String message, Throwable cause)119         public CannotLoadDatabaseMapDriverException(String message, Throwable cause) {
120             super(message, cause);
121         }
122     }
123 
124     @Retention(RetentionPolicy.RUNTIME)
125     @Target(ElementType.TYPE)
126     @Inherited
127     public @interface UsingDatabaseMap {
128         /**
129          * @return the classes to be run
130          */
value()131         public Class<? extends DatabaseMap> value();
132     }
133 }
134