KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > h2 > engine > Engine


1 /*
2  * Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
3  * Initial Developer: H2 Group
4  */

5 package org.h2.engine;
6
7 import java.sql.SQLException JavaDoc;
8 import java.util.HashMap JavaDoc;
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 /**
18  * @author Thomas
19  */

20 public class Engine {
21     // TODO use a 'engine'/'master' database to allow shut down the server, view & kill sessions and so on
22

23     private HashMap JavaDoc databases = new HashMap JavaDoc();
24     private static Engine instance = new Engine();
25
26     private Engine() {
27         // don't allow others to instantiate
28
}
29
30     public static Engine getInstance() {
31         return instance;
32     }
33
34     private Session openSession(ConnectionInfo ci, boolean ifExists, String JavaDoc cipher) throws SQLException JavaDoc {
35         // may not remove properties here, otherwise they are lost if it is required to call it twice
36
String JavaDoc 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                 // users is the last thing we add, so if no user is around, the database is not initialized correctly
48
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                         // reset - because the user is not an admin, and has no right to listen to exceptions
66
database.setEventListener(null);
67                     }
68                 } catch(SQLException JavaDoc 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 JavaDoc {
80         boolean ifExists = ci.removeProperty("IFEXISTS", false);
81         boolean ignoreUnknownSetting = ci.removeProperty("IGNORE_UNKNOWN_SETTINGS", false);
82         String JavaDoc 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             // we found a database that is currently closing
90
// wait a bit to avoid a busy loop
91
try {
92                 Thread.sleep(1);
93             } catch(InterruptedException JavaDoc e) {
94                 // ignore
95
}
96         }
97         String JavaDoc[] keys = ci.getKeys();
98         session.setAllowLiterals(true);
99         for(int i=0; i<keys.length; i++) {
100             String JavaDoc setting = keys[i];
101             String JavaDoc value = ci.getProperty(setting);
102             try {
103                 CommandInterface command = session.prepareCommand("SET " + Parser.quoteIdentifier(setting) + " " + value);
104                 command.executeUpdate();
105             } catch(SQLException JavaDoc 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 JavaDoc {
119         String JavaDoc clusterSession = ci.getProperty(SetTypes.CLUSTER, null);
120         if(Constants.CLUSTERING_DISABLED.equals(clusterSession)) {
121             // in this case, no checking is made
122
// (so that a connection can be made to disable/change clustering)
123
return;
124         }
125         String JavaDoc 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 JavaDoc name) {
138         databases.remove(name);
139     }
140
141 }
142
Popular Tags