1 5 package org.h2.engine; 6 7 import java.sql.SQLException ; 8 import java.util.HashMap ; 9 10 import org.h2.command.CommandInterface; 11 import org.h2.command.Parser; 12 import org.h2.command.dml.SetTypes; 13 import org.h2.message.Message; 14 import org.h2.message.Trace; 15 import org.h2.util.StringUtils; 16 17 20 public class Engine { 21 23 private HashMap databases = new HashMap (); 24 private static Engine instance = new Engine(); 25 26 private Engine() { 27 } 29 30 public static Engine getInstance() { 31 return instance; 32 } 33 34 private Session openSession(ConnectionInfo ci, boolean ifExists, String cipher) throws SQLException { 35 String name = ci.getName(); 37 Database database = (Database) databases.get(name); 38 User user = null; 39 boolean opened = false; 40 if(database == null) { 41 if(ifExists && !Database.exists(name)) { 42 throw Message.getSQLException(Message.DATABASE_NOT_FOUND_1, name); 43 } 44 database = new Database(name, ci, cipher); 45 opened = true; 46 if(database.getAllUsers().size()==0) { 47 user = new User(database, database.allocateObjectId(false, true), ci.getUserName(), false); 49 user.setAdmin(true); 50 user.setUserPasswordHash(ci.getUserPasswordHash()); 51 database.setMasterUser(user); 52 } 53 databases.put(name, database); 54 } 55 synchronized(database) { 56 if(database.isClosing()) { 57 return null; 58 } 59 if(user == null) { 60 try { 61 database.checkFilePasswordHash(cipher, ci.getFilePasswordHash()); 62 user = database.getUser(ci.getUserName()); 63 user.checkUserPasswordHash(ci.getUserPasswordHash()); 64 if(opened && !user.getAdmin()) { 65 database.setEventListener(null); 67 } 68 } catch(SQLException e) { 69 database.removeSession(null); 70 throw e; 71 } 72 } 73 checkClustering(ci, database); 74 Session session = database.createSession(user); 75 return session; 76 } 77 } 78 79 public synchronized Session getSession(ConnectionInfo ci) throws SQLException { 80 boolean ifExists = ci.removeProperty("IFEXISTS", false); 81 boolean ignoreUnknownSetting = ci.removeProperty("IGNORE_UNKNOWN_SETTINGS", false); 82 String cipher = ci.removeProperty("CIPHER", null); 83 Session session; 84 while(true) { 85 session = openSession(ci, ifExists, cipher); 86 if(session != null) { 87 break; 88 } 89 try { 92 Thread.sleep(1); 93 } catch(InterruptedException e) { 94 } 96 } 97 String [] keys = ci.getKeys(); 98 session.setAllowLiterals(true); 99 for(int i=0; i<keys.length; i++) { 100 String setting = keys[i]; 101 String value = ci.getProperty(setting); 102 try { 103 CommandInterface command = session.prepareCommand("SET " + Parser.quoteIdentifier(setting) + " " + value); 104 command.executeUpdate(); 105 } catch(SQLException e) { 106 if(!ignoreUnknownSetting) { 107 session.close(); 108 throw e; 109 } 110 } 111 } 112 session.setAllowLiterals(false); 113 session.commit(); 114 session.getDatabase().getTrace(Trace.SESSION).info("connected #" + session.getId()); 115 return session; 116 } 117 118 private void checkClustering(ConnectionInfo ci, Database database) throws SQLException { 119 String clusterSession = ci.getProperty(SetTypes.CLUSTER, null); 120 if(Constants.CLUSTERING_DISABLED.equals(clusterSession)) { 121 return; 124 } 125 String clusterDb = database.getCluster(); 126 if(!Constants.CLUSTERING_DISABLED.equals(clusterDb)) { 127 if(!StringUtils.equals(clusterSession, clusterDb)) { 128 if(clusterDb.equals(Constants.CLUSTERING_DISABLED)) { 129 throw Message.getSQLException(Message.CLUSTER_ERROR_DATABASE_RUNS_ALONE); 130 } else { 131 throw Message.getSQLException(Message.CLUSTER_ERROR_DATABASE_RUNS_CLUSTERED_1, clusterDb); 132 } 133 } 134 } 135 } 136 137 public void close(String name) { 138 databases.remove(name); 139 } 140 141 } 142 | Popular Tags |