KickJava   Java API By Example, From Geeks To Geeks.

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


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 import java.util.HashSet JavaDoc;
10 import java.util.Iterator JavaDoc;
11 import java.util.Random JavaDoc;
12
13 import org.h2.command.Command;
14 import org.h2.command.CommandInterface;
15 import org.h2.command.Parser;
16 import org.h2.command.Prepared;
17 import org.h2.command.dml.SetTypes;
18 import org.h2.jdbc.JdbcConnection;
19 import org.h2.message.Message;
20 import org.h2.message.Trace;
21 import org.h2.message.TraceSystem;
22 import org.h2.schema.Schema;
23 import org.h2.store.DataHandler;
24 import org.h2.store.InDoubtTransaction;
25 import org.h2.store.LogSystem;
26 import org.h2.store.UndoLog;
27 import org.h2.store.UndoLogRecord;
28 import org.h2.table.Table;
29 import org.h2.table.TableData;
30 import org.h2.util.ObjectArray;
31 import org.h2.value.Value;
32
33 /**
34  * @author Thomas
35  */

36 public class Session implements SessionInterface {
37     private User user;
38     private int id;
39     private Database database;
40     private ObjectArray locks = new ObjectArray();
41     // TODO big transactions: rollback log should be a sorted result set,
42
// so that big transactions are possible (delete or update huge tables)
43
private UndoLog undoLog;
44     private boolean autoCommit = true;
45     // TODO function RANDOM: use a own implementation, making it system independent
46
private Random JavaDoc random;
47     private LogSystem logSystem;
48     private int lockTimeout;
49     private long lastIdentity;
50     private int firstUncommittedLog = LogSystem.LOG_WRITTEN;
51     private int firstUncommittedPos = LogSystem.LOG_WRITTEN;
52     private HashMap JavaDoc savepoints;
53     private Exception JavaDoc stackTrace = new Exception JavaDoc();
54     private HashMap JavaDoc localTempTables;
55     private int throttle;
56     private long lastThrottle;
57     private Command currentCommand;
58     private boolean allowLiterals;
59     private String JavaDoc currentSchemaName;
60     private String JavaDoc traceModuleName;
61     private HashSet JavaDoc unlinkSet;
62
63     public Table findLocalTempTable(String JavaDoc name) {
64         Table t = null;
65         if(t == null && localTempTables != null) {
66             t = (Table) localTempTables.get(name);
67         }
68         return t;
69     }
70
71     public ObjectArray getLocalTempTables() {
72         if(localTempTables == null) {
73             return new ObjectArray();
74         }
75         ObjectArray list = new ObjectArray(localTempTables.values());
76         return list;
77     }
78
79     public String JavaDoc getNewLocalTempTransactionTableName() {
80         // TODO this is current not used
81
String JavaDoc name = Constants.TEMP_TABLE_TRANSACTION_PREFIX;
82         for(int i=0; ; i++) {
83             String JavaDoc n = name + i;
84             if(findLocalTempTable(n) == null) {
85                 return n;
86             }
87         }
88     }
89
90     public void addLocalTempTable(TableData table) throws SQLException JavaDoc {
91         cleanTempTables();
92         if(localTempTables == null) {
93             localTempTables = new HashMap JavaDoc();
94         }
95         if(localTempTables.get(table.getName()) != null) {
96             throw Message.getSQLException(Message.TABLE_OR_VIEW_ALREADY_EXISTS_1, table.getSQL());
97         }
98         localTempTables.put(table.getName(), table);
99     }
100
101     public void removeLocalTempTable(Table table) throws SQLException JavaDoc {
102         localTempTables.remove(table.getName());
103         table.removeChildrenAndResources(this);
104     }
105
106     protected void finalize() {
107         if(!Constants.RUN_FINALIZERS) {
108             return;
109         }
110         if(database != null) {
111             throw Message.getInternalError("not closed", stackTrace);
112         }
113     }
114
115     public boolean getAutoCommit() {
116         return autoCommit;
117     }
118
119     public User getUser() {
120         return user;
121     }
122
123     public void setAutoCommit(boolean b) {
124         autoCommit = b;
125     }
126
127     public int getLockTimeout() {
128         return lockTimeout;
129     }
130
131     public void setLockTimeout(int lockTimeout) {
132         this.lockTimeout = lockTimeout;
133     }
134
135     public Session() {
136
137     }
138
139     public SessionInterface createSession(ConnectionInfo ci) throws SQLException JavaDoc {
140         return Engine.getInstance().getSession(ci);
141     }
142
143     Session(Database database, User user, int id) {
144         this.database = database;
145         this.undoLog = new UndoLog(this);
146         this.user = user;
147         this.id = id;
148         this.logSystem = database.getLog();
149         Setting setting = database.findSetting(SetTypes.getTypeName(SetTypes.DEFAULT_LOCK_TIMEOUT));
150         this.lockTimeout = setting == null ? Constants.INITIAL_LOCK_TIMEOUT : setting.getIntValue();
151         this.currentSchemaName = Constants.SCHEMA_MAIN;
152     }
153     
154     public CommandInterface prepareCommand(String JavaDoc sql) throws SQLException JavaDoc {
155         return prepareLocal(sql);
156     }
157
158     public Prepared prepare(String JavaDoc sql) throws SQLException JavaDoc {
159         return prepare(sql, false);
160     }
161
162     public Prepared prepare(String JavaDoc sql, boolean rightsChecked) throws SQLException JavaDoc {
163         Parser parser = new Parser(this);
164         parser.setRightsChecked(rightsChecked);
165         return parser.prepare(sql);
166     }
167
168     public Command prepareLocal(String JavaDoc sql) throws SQLException JavaDoc {
169         if(database == null) {
170             throw Message.getSQLException(Message.CONNECTION_BROKEN);
171         }
172         Parser parser = new Parser(this);
173         return parser.prepareCommand(sql);
174     }
175
176     public Database getDatabase() {
177         return database;
178     }
179
180     public int getPowerOffCount() {
181         return database == null ? 0 : database.getPowerOffCount();
182     }
183
184     public void setPowerOffCount(int count) {
185         if(database != null) {
186             database.setPowerOffCount(count);
187         }
188     }
189
190     public void commit() throws SQLException JavaDoc {
191         if(containsUncommitted()) {
192             // need to commit even if rollback is not possible (create/drop table and so on)
193
logSystem.commit(this);
194         }
195         if(undoLog.size() > 0) {
196             undoLog.clear();
197             cleanTempTables();
198         }
199         if(unlinkSet != null && unlinkSet.size() > 0) {
200             // need to flush the log file, because we can't unlink lobs if the commit record is not written
201
logSystem.flush();
202             Iterator JavaDoc it = unlinkSet.iterator();
203             while(it.hasNext()) {
204                 Value v = (Value) it.next();
205                 v.unlink(database);
206             }
207             unlinkSet = null;
208         }
209         unlockAll();
210     }
211
212     public void rollback() throws SQLException JavaDoc {
213         boolean needCommit = false;
214         if (undoLog.size() > 0) {
215             rollbackTo(0);
216             needCommit = true;
217         }
218         if(locks.size() > 0 || needCommit) {
219             logSystem.commit(this);
220         }
221         cleanTempTables();
222         unlockAll();
223     }
224
225     public void rollbackTo(int index) throws SQLException JavaDoc {
226         while (undoLog.size() > index) {
227             UndoLogRecord entry = undoLog.getAndRemoveLast();
228             entry.undo(this);
229         }
230         if(savepoints != null) {
231             String JavaDoc[] names = new String JavaDoc[savepoints.size()];
232             savepoints.keySet().toArray(names);
233             for(int i=0; i<names.length; i++) {
234                 String JavaDoc name = names[i];
235                 Integer JavaDoc id = (Integer JavaDoc) savepoints.get(names[i]);
236                 if(id.intValue() > index) {
237                     savepoints.remove(name);
238                 }
239             }
240         }
241     }
242
243     public int getLogId() {
244         return undoLog.size();
245     }
246
247     public int getId() {
248         return id;
249     }
250
251     public void close() throws SQLException JavaDoc {
252         if(database != null) {
253             try {
254                 database.removeSession(this);
255             } finally {
256                 database = null;
257             }
258         }
259     }
260
261     public void addLock(Table table) {
262         if(Constants.CHECK) {
263             if(locks.indexOf(table)>=0) {
264                 throw Message.getInternalError();
265             }
266         }
267         locks.add(table);
268     }
269
270     public void log(UndoLogRecord log) throws SQLException JavaDoc {
271         // called _after_ the row was inserted successfully into the table,
272
// otherwise rollback will try to rollback a not-inserted row
273
if(Constants.CHECK) {
274             int lockMode = database.getLockMode();
275             if(lockMode != Constants.LOCK_MODE_OFF) {
276                 if(locks.indexOf(log.getTable())<0 && log.getTable().getTableType() != Table.TABLE_LINK) {
277                     throw Message.getInternalError();
278                 }
279             }
280         }
281         undoLog.add(log);
282     }
283
284     private void unlockAll() throws SQLException JavaDoc {
285         if(Constants.CHECK) {
286             if(undoLog.size() > 0) {
287                 throw Message.getInternalError();
288             }
289         }
290         for(int i=0; i<locks.size(); i++) {
291             Table t = (Table)locks.get(i);
292             t.unlock(this);
293         }
294         locks.clear();
295         savepoints = null;
296     }
297
298     private void cleanTempTables() throws SQLException JavaDoc {
299         if(localTempTables != null && localTempTables.size()>0) {
300             ObjectArray list = new ObjectArray(localTempTables.values());
301             for(int i=0; i<list.size(); i++) {
302                 TableData table = (TableData) list.get(i);
303                 if(table.isOnCommitDrop()) {
304                     table.setModified();
305                     localTempTables.remove(table.getName());
306                     table.removeChildrenAndResources(this);
307                 } else if(table.isOnCommitTruncate()) {
308                     table.truncate(this);
309                 }
310             }
311         }
312     }
313
314     public Random JavaDoc getRandom() {
315         if(random == null) {
316             random = new Random JavaDoc();
317         }
318         return random;
319     }
320
321     public Trace getTrace() {
322         if(traceModuleName == null) {
323             traceModuleName = Trace.JDBC + "[" + id + "]";
324         }
325         if(database == null) {
326             return new TraceSystem(null).getTrace(traceModuleName);
327         }
328         return database.getTrace(traceModuleName);
329     }
330
331     public void setLastIdentity(long last) {
332         this.lastIdentity = last;
333     }
334
335     public long getLastIdentity() {
336         return lastIdentity;
337     }
338
339     public void addLogPos(int logId, int pos) {
340         if (firstUncommittedLog == LogSystem.LOG_WRITTEN) {
341             firstUncommittedLog = logId;
342             firstUncommittedPos = pos;
343         }
344     }
345
346     public int getFirstUncommittedLog() {
347         return firstUncommittedLog;
348     }
349
350     public int getFirstUncommittedPos() {
351         return firstUncommittedPos;
352     }
353
354     public void setAllCommitted() {
355         firstUncommittedLog = LogSystem.LOG_WRITTEN;
356         firstUncommittedPos = LogSystem.LOG_WRITTEN;
357     }
358
359     private boolean containsUncommitted() {
360         return firstUncommittedLog != LogSystem.LOG_WRITTEN;
361     }
362
363     public void addSavepoint(String JavaDoc name) {
364         if(savepoints == null) {
365             savepoints = new HashMap JavaDoc();
366         }
367         savepoints.put(name, new Integer JavaDoc(getLogId()));
368     }
369
370     public void rollbackToSavepoint(String JavaDoc name) throws SQLException JavaDoc {
371         if(savepoints == null) {
372             throw Message.getSQLException(Message.SAVEPOINT_IS_INVALID_1, name);
373         }
374         Integer JavaDoc id = (Integer JavaDoc)savepoints.get(name);
375         if(id==null) {
376             throw Message.getSQLException(Message.SAVEPOINT_IS_INVALID_1, name);
377         }
378         int i = id.intValue();
379         rollbackTo(i);
380     }
381
382     public void prepareCommit(String JavaDoc transactionName) throws SQLException JavaDoc {
383         if(containsUncommitted()) {
384             // need to commit even if rollback is not possible (create/drop table and so on)
385
logSystem.prepareCommit(this, transactionName);
386         }
387     }
388
389     public void setPreparedTransaction(String JavaDoc transactionName, boolean commit) throws SQLException JavaDoc {
390         ObjectArray list = logSystem.getInDoubtTransactions();
391         int state = commit ? InDoubtTransaction.COMMIT : InDoubtTransaction.ROLLBACK;
392         for(int i=0; list!=null && i<list.size(); i++) {
393             InDoubtTransaction p = (InDoubtTransaction)list.get(i);
394             if(p.getTransaction().equals(transactionName)) {
395                 p.setState(state);
396             }
397         }
398     }
399
400     public boolean isClosed() {
401         return database == null;
402     }
403
404     public void setThrottle(int throttle) {
405         this.throttle = throttle;
406     }
407
408     public void throttle() {
409         if(throttle == 0) {
410             return;
411         }
412         long time = System.currentTimeMillis();
413         if(lastThrottle + Constants.THROTTLE_DELAY > time) {
414             return;
415         }
416         lastThrottle = time + throttle;
417         try {
418             Thread.sleep(throttle);
419         } catch(Exception JavaDoc e) {
420             // ignore
421
}
422     }
423
424     public void setCurrentCommand(Command command) {
425         this.currentCommand = command;
426     }
427
428     public void checkCancelled() throws SQLException JavaDoc {
429         if(currentCommand != null) {
430             currentCommand.checkCancelled();
431         }
432     }
433
434     public boolean getAllowLiterals() {
435         return allowLiterals;
436     }
437
438     public void setAllowLiterals(boolean b) {
439         this.allowLiterals = b;
440     }
441
442     public void setCurrentSchema(Schema schema) {
443         this.currentSchemaName = schema.getName();
444     }
445
446     public String JavaDoc getCurrentSchemaName() {
447         return currentSchemaName;
448     }
449     
450     public JdbcConnection createConnection(boolean columnList) throws SQLException JavaDoc {
451         String JavaDoc url;
452         if(columnList) {
453             url = Constants.CONN_URL_COLUMNLIST;
454         } else {
455             url = Constants.CONN_URL_INTERNAL;
456         }
457         return new JdbcConnection(this, getUser().getName(), url);
458     }
459     
460     public DataHandler getDataHandler() {
461         return database;
462     }
463
464     public void unlinkAtCommit(Value v) {
465         if(unlinkSet == null) {
466             unlinkSet = new HashSet JavaDoc();
467         }
468         unlinkSet.add(v);
469     }
470     
471     public void unlinkAtCommitStop(Value v) {
472         if(unlinkSet != null) {
473             unlinkSet.remove(v);
474         }
475     }
476
477 }
478
Popular Tags