View Javadoc

1   package de.mxro.async.map.sql;
2   
3   import java.sql.CallableStatement;
4   import java.sql.Connection;
5   import java.sql.SQLException;
6   
7   import de.mxro.async.map.AsyncMap;
8   import de.mxro.async.map.AsyncMaps;
9   import de.mxro.async.map.sql.internal.EncodeCaseInsensitiveKey;
10  import de.mxro.async.map.sql.internal.SqlAsyncMapImplementation;
11  import de.mxro.async.map.sql.internal.SqlConnectionFactory;
12  
13  /**
14   * <p>
15   * Core methods to interact with async-map-sql module.
16   * <p>
17   * Use {@link #createMap(SqlAsyncMapConfiguration, SqlAsyncMapDependencies)} to
18   * create new SQL backed up AsyncMaps.
19   * 
20   * @author <a href="http://www.mxro.de">Max Rohde</a>
21   *
22   */
23  public final class AsyncMapSql {
24  
25      /**
26       * Creates a new AsyncMap persisted by a JDBC compatible SQL database.
27       * 
28       * @param conf
29       *            Configuration for this map.
30       * @param deps
31       *            Run-time dependencies for the maps.
32       * @return
33       */
34      public static final <V> AsyncMap<String, V> createMap(final SqlAsyncMapConfiguration conf,
35              final SqlAsyncMapDependencies deps) {
36          return new SqlAsyncMapImplementation<V>(conf, deps);
37      }
38  
39      public static final SqlAsyncMapConfiguration fromSqlConfiguration(final SqlConnectionConfiguration sqlConf) {
40          return new SqlAsyncMapConfiguration() {
41  
42              @Override
43              public SqlConnectionConfiguration sql() {
44                  return sqlConf;
45              }
46          };
47      }
48  
49      public static final void assertTable(final SqlConnectionConfiguration sqlConf) {
50          final Connection connection = SqlConnectionFactory.createConnection(sqlConf);
51  
52          try {
53              final CallableStatement statement = connection.prepareCall("CREATE TABLE IF NOT EXISTS "
54                      + sqlConf.getTableName() + "(ID VARCHAR(512) PRIMARY KEY, VALUE BLOB);");
55  
56              statement.execute();
57  
58              /*
59               * Don't close the connection for H2 in memory databases. Closing
60               * the connection would wipe the created table.
61               */
62              if (!sqlConf.getConnectionString().contains(":mem:")) {
63                  connection.close();
64              }
65  
66          } catch (final SQLException e) {
67              throw new RuntimeException(e);
68          }
69      }
70  
71      /**
72       * <p>
73       * Some databases (such as MySQL) store keys case insensitive by default.
74       * This decorator allows to preserve the semantic information of case
75       * sensitive keys when storing them with a case insensitive storage engine.
76       * <p>
77       * Very useful for URLs as keys.
78       * <p>
79       * Keys are not allowed to contain the character '^'.
80       * 
81       * @param map
82       * @return
83       */
84      public static final <V> AsyncMap<String, V> encodeKeysForCaseInsensitiveStorage(final AsyncMap<String, V> map) {
85          return AsyncMaps.filterKeys(new EncodeCaseInsensitiveKey(), map);
86      }
87  
88  }