Source Code Cross Referenced for Database.java in  » Database-DBMS » perst » org » garret » perst » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database DBMS » perst » org.garret.perst 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package org.garret.perst;
002:
003:        import java.util.*;
004:        import java.lang.reflect.*;
005:        import org.garret.perst.impl.ClassDescriptor;
006:
007:        /**
008:         * This class emulates relational database on top of Perst storage
009:         * It maintain class extends, associated indices, prepare queries.
010:         */
011:        public class Database {
012:            /** 
013:             * Constructor of database. This method initialize database if it not initialized yet.
014:             * Starting from 2.72 version of Perst.Net, it supports automatic
015:             * creation of table descriptors when Database class is used.
016:             * So now it is not necessary to explicitly create tables and indices -
017:             * the Database class will create them itself on demand.
018:             * Indexable attribute should be used to mark key fields for which index should be created.
019:             * Table descriptor is created when instance of the correspondent class is first time stored 
020:             * in the database. Perst creates table descriptors for all derived classes up
021:             * to the root java.lang.Object class.
022:             * @param storage opened storage. Storage should be either empty (non-initialized, either
023:             * previously initialized by the this method. It is not possible to open storage with 
024:             * root object other than table index created by this constructor.
025:             * @param multithreaded <code>true</code> if database should support concurrent access
026:             * to the data from multiple threads.
027:             */
028:            public Database(Storage storage, boolean multithreaded) {
029:                this (storage, multithreaded, true);
030:            }
031:
032:            /** 
033:             * Constructor of database. This method initialize database if it not initialized yet.
034:             * @param storage opened storage. Storage should be either empty (non-initialized, either
035:             * previously initialized by the this method. It is not possible to open storage with 
036:             * root object other than table index created by this constructor.
037:             * @param multithreaded <code>true</code> if database should support concurrent access
038:             * to the data from multiple threads.
039:             * @param autoRegisterTables automatically create tables descriptors for instances of new 
040:             * classes inserted in the database
041:             */
042:            public Database(Storage storage, boolean multithreaded,
043:                    boolean autoRegisterTables) {
044:                this .storage = storage;
045:                this .multithreaded = multithreaded;
046:                this .autoRegisterTables = autoRegisterTables;
047:                if (multithreaded) {
048:                    storage
049:                            .setProperty("perst.alternative.btree",
050:                                    Boolean.TRUE);
051:                }
052:                metadata = (Index) storage.getRoot();
053:                boolean schemaUpdated = false;
054:                if (metadata == null) {
055:                    beginTransaction();
056:                    metadata = storage.createIndex(String.class, true);
057:                    storage.setRoot(metadata);
058:                    schemaUpdated = true;
059:                }
060:                Iterator iterator = metadata.entryIterator();
061:                tables = new HashMap();
062:                while (iterator.hasNext()) {
063:                    Map.Entry map = (Map.Entry) iterator.next();
064:                    Table table = (Table) map.getValue();
065:                    Class cls = ClassDescriptor.loadClass(storage, (String) map
066:                            .getKey());
067:                    tables.put(cls, table);
068:                    schemaUpdated |= addIndices(table, cls);
069:                }
070:                if (schemaUpdated) {
071:                    commitTransaction();
072:                }
073:            }
074:
075:            /** 
076:             * Constructor of single threaded database. This method initialize database if it not initialized yet.
077:             * @param storage opened storage. Storage should be either empty (non-initialized, either
078:             * previously initialized by the this method. It is not possible to open storage with 
079:             * root object other than table index created by this constructor.
080:             */
081:            public Database(Storage storage) {
082:                this (storage, false);
083:            }
084:
085:            /**
086:             * Begin transaction
087:             */
088:            public void beginTransaction() {
089:                if (multithreaded) {
090:                    storage
091:                            .beginThreadTransaction(Storage.SERIALIZABLE_TRANSACTION);
092:                }
093:            }
094:
095:            /**
096:             * Commit transaction
097:             */
098:            public void commitTransaction() {
099:                if (multithreaded) {
100:                    storage.endThreadTransaction();
101:                } else {
102:                    storage.commit();
103:                }
104:            }
105:
106:            /**
107:             * Rollback transaction
108:             */
109:            public void rollbackTransaction() {
110:                if (multithreaded) {
111:                    storage.rollbackThreadTransaction();
112:                } else {
113:                    storage.rollback();
114:                }
115:            }
116:
117:            /**
118:             * Create table for the specified class.
119:             * This function does nothing if table for such class already exists
120:             * @param table class corresponding to the table
121:             * @return <code>true</code> if table is created, <code>false</code> if table 
122:             * alreay exists
123:             * @deprecated Since version 2.75 of Perst it is not necessary to create table and index 
124:             * descriptors explicitly: them are automatically create when object is inserted in the 
125:             * database first time (to mark fields for which indices should be created, use Indexable 
126:             * annotation)
127:             */
128:            public boolean createTable(Class table) {
129:                if (multithreaded) {
130:                    metadata.exclusiveLock();
131:                }
132:                if (tables.get(table) == null) {
133:                    Table t = new Table();
134:                    t.extent = storage.createSet();
135:                    t.indices = storage.createLink();
136:                    t.indicesMap = new HashMap();
137:                    tables.put(table, t);
138:                    metadata.put(table.getName(), t);
139:                    addIndices(t, table);
140:                    return true;
141:                }
142:                return false;
143:            }
144:
145:            private boolean addIndices(Table table, Class cls) {
146:                boolean schemaUpdated = false;
147:                for (Field f : cls.getDeclaredFields()) {
148:                    Indexable idx = (Indexable) f
149:                            .getAnnotation(Indexable.class);
150:                    if (idx != null) {
151:                        schemaUpdated |= createIndex(table, cls, f.getName(),
152:                                idx.unique(), idx.caseInsensitive());
153:                    }
154:                }
155:                return schemaUpdated;
156:            }
157:
158:            /**
159:             * Drop table associated with this class. Do nothing if there is no such table in the database.
160:             * @param table class corresponding to the table
161:             * @return <code>true</code> if table is deleted, <code>false</code> if table 
162:             * is not found
163:             */
164:            public boolean dropTable(Class table) {
165:                if (multithreaded) {
166:                    metadata.exclusiveLock();
167:                }
168:                if (tables.remove(table) != null) {
169:                    metadata.remove(table.getName());
170:                    return true;
171:                }
172:                return false;
173:            }
174:
175:            /**
176:             * Add new record to the table. Record is inserted in table corresponding to the class of the object.
177:             * Record will be automatically added to all indices existed for this table.
178:             * If there is not table associated with class of this object, then 
179:             * database will search for table associated with superclass and so on...
180:             * @param record object to be inserted in the table
181:             * @return <code>true</code> if record was successfully added to the table, <code>false</code>
182:             * if there is already such record (object with the same ID) in the table or there is some record with the same value of 
183:             * unique key field
184:             * @exception StorageError(CLASS_NOT_FOUND) exception is thrown if there is no table corresponding to 
185:             * record class
186:             */
187:            public <T extends IPersistent> boolean addRecord(T record) {
188:                return addRecord(record.getClass(), record);
189:            }
190:
191:            private Table locateTable(Class cls, boolean exclusive) {
192:                return locateTable(cls, exclusive, true);
193:            }
194:
195:            private Table locateTable(Class cls, boolean exclusive,
196:                    boolean shouldExist) {
197:                Table table = null;
198:                if (multithreaded) {
199:                    metadata.sharedLock();
200:                }
201:                for (Class c = cls; c != null
202:                        && (table = (Table) tables.get(c)) == null; c = c
203:                        .getSuperclass())
204:                    ;
205:                if (table == null) {
206:                    if (shouldExist) {
207:                        throw new StorageError(StorageError.CLASS_NOT_FOUND,
208:                                cls.getName());
209:                    }
210:                    return null;
211:                }
212:                if (exclusive) {
213:                    table.extent.exclusiveLock();
214:                } else {
215:                    table.extent.sharedLock();
216:                }
217:                return table;
218:            }
219:
220:            private void registerTable(Class cls) {
221:                if (multithreaded) {
222:                    metadata.sharedLock();
223:                }
224:                if (autoRegisterTables) {
225:                    boolean exclusiveLockSet = false;
226:                    for (Class c = cls; c != Object.class; c = c
227:                            .getSuperclass()) {
228:                        Table t = (Table) tables.get(c);
229:                        if (t == null) {
230:                            if (!exclusiveLockSet) {
231:                                metadata.unlock(); // try to avoid deadlock caused by concurrent insertion of objects
232:                                exclusiveLockSet = true;
233:                            }
234:                            createTable(c);
235:                        }
236:                    }
237:                }
238:            }
239:
240:            /**
241:             * Add new record to the specified table. Record is inserted in table corresponding to the specified class.
242:             * Record will be automatically added to all indices existed for this table.
243:             * @param table class corresponding to the table
244:             * @param record object to be inserted in the table
245:             * @return <code>true</code> if record was successfully added to the table, <code>false</code>
246:             * if there is already such record (object with the same ID) in the table or there is some record with the same value of 
247:             * unique key field
248:             * @exception StorageError(CLASS_NOT_FOUND) exception is thrown if there is no table corresponding to 
249:             * record class
250:             */
251:            public <T extends IPersistent> boolean addRecord(Class table,
252:                    T record) {
253:                boolean added = false;
254:                boolean found = false;
255:                registerTable(table);
256:                ArrayList wasInsertedIn = new ArrayList();
257:                for (Class c = table; c != null; c = c.getSuperclass()) {
258:                    Table t = (Table) tables.get(c);
259:                    if (t != null) {
260:                        found = true;
261:                        if (multithreaded) {
262:                            t.extent.exclusiveLock();
263:                        }
264:                        if (t.extent.add(record)) {
265:                            wasInsertedIn.add(t.extent);
266:                            Iterator iterator = t.indicesMap.values()
267:                                    .iterator();
268:                            while (iterator.hasNext()) {
269:                                FieldIndex index = (FieldIndex) iterator.next();
270:                                if (index.put(record)) {
271:                                    wasInsertedIn.add(index);
272:                                } else {
273:                                    iterator = wasInsertedIn.iterator();
274:                                    while (iterator.hasNext()) {
275:                                        Object idx = iterator.next();
276:                                        if (idx instanceof  IPersistentSet) {
277:                                            ((IPersistentSet) idx)
278:                                                    .remove(record);
279:                                        } else {
280:                                            ((FieldIndex) idx).remove(record);
281:                                        }
282:                                    }
283:                                    return false;
284:                                }
285:                            }
286:                            added = true;
287:                        }
288:                    }
289:                }
290:                if (!found) {
291:                    throw new StorageError(StorageError.CLASS_NOT_FOUND, table
292:                            .getName());
293:                }
294:                return added;
295:            }
296:
297:            /** 
298:             * Delete record from the table. Record is removed from the table corresponding to the class 
299:             * of the object. Record will be automatically added to all indices existed for this table.
300:             * If there is not table associated with class of this object, then 
301:             * database will search for table associated with superclass and so on...
302:             * Object represented the record will be also deleted from the storage.
303:             * @param record object to be deleted from the table
304:             * @return <code>true</code> if record was successfully deleted from the table, <code>false</code>
305:             * if there is not such record (object with the same ID) in the table
306:             * @exception StorageError(CLASS_NOT_FOUND) exception is thrown if there is no table corresponding to 
307:             * record class
308:             */
309:            public <T extends IPersistent> boolean deleteRecord(T record) {
310:                return deleteRecord(record.getClass(), record);
311:            }
312:
313:            /** 
314:             * Delete record from the specified table. Record is removed from the table corresponding to the 
315:             * specified class. Record will be automatically added to all indices existed for this table.
316:             * Object represented the record will be also deleted from the storage.
317:             * @param table class corresponding to the table
318:             * @param record object to be deleted from the table
319:             * @return <code>true</code> if record was successfully deleted from the table, <code>false</code>
320:             * if there is not such record (object with the same ID) in the table
321:             * @exception StorageError(CLASS_NOT_FOUND) exception is thrown if there is no table corresponding to 
322:             * specified class
323:             */
324:            public <T extends IPersistent> boolean deleteRecord(Class table,
325:                    T record) {
326:                boolean removed = false;
327:                if (multithreaded) {
328:                    metadata.sharedLock();
329:                }
330:                for (Class c = table; c != null; c = c.getSuperclass()) {
331:                    Table t = (Table) tables.get(c);
332:                    if (t != null) {
333:                        if (multithreaded) {
334:                            t.extent.exclusiveLock();
335:                        }
336:                        if (t.extent.remove(record)) {
337:                            Iterator iterator = t.indicesMap.values()
338:                                    .iterator();
339:                            while (iterator.hasNext()) {
340:                                FieldIndex index = (FieldIndex) iterator.next();
341:                                index.remove(record);
342:                            }
343:                            removed = true;
344:                        }
345:                    }
346:                }
347:                if (removed) {
348:                    record.deallocate();
349:                }
350:                return removed;
351:            }
352:
353:            /**
354:             * Add new index to the table. If such index already exists this method does nothing.
355:             * @param table class corresponding to the table
356:             * @param key field of the class to be indexed
357:             * @param unique if index is unique or not
358:             * @exception StorageError(CLASS_NOT_FOUND) exception is thrown if there is no table corresponding to 
359:             * the specified class
360:             * @return <code>true</code> if index is created, <code>false</code> if index
361:             * already exists
362:             * @deprecated since version 2.75 of Perst it is not necessary to create table and index 
363:             * descriptors explicitly: them are automatically create when object is inserted in the 
364:             * database first time (to mark fields for which indices should be created, use Indexable 
365:             * annotation)
366:             */
367:            public boolean createIndex(Class table, String key, boolean unique) {
368:                return createIndex(locateTable(table, true), table, key,
369:                        unique, false);
370:            }
371:
372:            /**
373:             * Add new index to the table. If such index already exists this method does nothing.
374:             * @param table class corresponding to the table
375:             * @param key field of the class to be indexed
376:             * @param unique if index is unique or not
377:             * @param caseInsensitive if string index is case insensitive
378:             * @exception StorageError(CLASS_NOT_FOUND) exception is thrown if there is no table corresponding to 
379:             * the specified class
380:             * @return <code>true</code> if index is created, <code>false</code> if index
381:             * already exists
382:             * @deprecated since version 2.75 of Perst it is not necessary to create table and index 
383:             * descriptors explicitly: them are automatically cerate when objct is inserted in the 
384:             * database first time (to mark fields for which indices should be created, use Indexable 
385:             * annotaion)
386:             */
387:            public boolean createIndex(Class table, String key, boolean unique,
388:                    boolean caseInsensitive) {
389:                return createIndex(locateTable(table, true), table, key,
390:                        unique, caseInsensitive);
391:            }
392:
393:            private boolean createIndex(Table t, Class c, String key,
394:                    boolean unique, boolean caseInsensitive) {
395:                if (t.indicesMap.get(key) == null) {
396:                    FieldIndex index = storage.createFieldIndex(c, key, unique,
397:                            caseInsensitive);
398:                    t.indicesMap.put(key, index);
399:                    t.indices.add(index);
400:                    return true;
401:                }
402:                return false;
403:            }
404:
405:            /**
406:             * Drop index for the specified table and key.
407:             * Does nothing if there is no such index.
408:             * @param table class corresponding to the table
409:             * @param key field of the class to be indexed
410:             * @exception StorageError(CLASS_NOT_FOUND) exception is thrown if there is no table corresponding to 
411:             * the specified class
412:             * @return <code>true</code> if index is deleted, <code>false</code> if index 
413:             * is not found
414:             */
415:            public boolean dropIndex(Class table, String key) {
416:                Table t = locateTable(table, true);
417:                FieldIndex index = (FieldIndex) t.indicesMap.remove(key);
418:                if (index != null) {
419:                    t.indices.remove(t.indices.indexOf(index));
420:                    return true;
421:                }
422:                return false;
423:            }
424:
425:            /**
426:             * Get indices for the specified table
427:             * @param table class corresponding to the table
428:             * @return map of table indices
429:             */
430:            public HashMap getIndices(Class table) {
431:                Table t = locateTable(table, true, false);
432:                return t == null ? new HashMap() : t.indicesMap;
433:            }
434:
435:            /**
436:             * Exclude record from specified index. This method is needed to perform update of indexed
437:             * field (key). Before updating the record, it is necessary to exclude it from indices
438:             * which keys are affected. After updating the field, record should be reinserted in these indices
439:             * using includeInIndex method.<P>
440:             * If there is not table associated with class of this object, then 
441:             * database will search for table associated with superclass and so on...<P>
442:             * This method does nothing if there is no index for the specified field.
443:             * @param record object to be excluded from the specified index
444:             * @param key name of the indexed field
445:             * @exception StorageError(CLASS_NOT_FOUND) exception is thrown if there is no table corresponding to 
446:             * record class
447:             * @return <code>true</code> if record is excluded from index, <code>false</code> if 
448:             * there is no such index
449:             */
450:            public boolean excludeFromIndex(IPersistent record, String key) {
451:                return excludeFromIndex(record.getClass(), record, key);
452:            }
453:
454:            /**
455:             * Exclude record from specified index. This method is needed to perform update of indexed
456:             * field (key). Before updating the record, it is necessary to exclude it from indices
457:             * which keys are affected. After updating the field, record should be reinserted in these indices
458:             * using includeInIndex method.<P>
459:             * If there is not table associated with class of this object, then 
460:             * database will search for table associated with superclass and so on...<P>
461:             * This method does nothing if there is no index for the specified field.
462:             * @param table class corresponding to the table
463:             * @param record object to be excluded from the specified index
464:             * @param key name of the indexed field
465:             * @exception StorageError(CLASS_NOT_FOUND) exception is thrown if there is no table corresponding to 
466:             * the specified class
467:             * @return <code>true</code> if record is excluded from index, <code>false</code> if 
468:             * there is no such index
469:             */
470:            public boolean excludeFromIndex(Class table, IPersistent record,
471:                    String key) {
472:                Table t = locateTable(table, true);
473:                FieldIndex index = (FieldIndex) t.indicesMap.get(key);
474:                if (index != null) {
475:                    index.remove(record);
476:                    return true;
477:                }
478:                return false;
479:            }
480:
481:            /**
482:             * Include record in the specified index. This method is needed to perform update of indexed
483:             * field (key). Before updating the record, it is necessary to exclude it from indices
484:             * which keys are affected using excludeFromIndex method. After updating the field, record should be 
485:             * reinserted in these indices using this method.<P>
486:             * If there is not table associated with class of this object, then 
487:             * database will search for table associated with superclass and so on...<P>
488:             * This method does nothing if there is no index for the specified field.
489:             * @param record object to be excluded from the specified index
490:             * @param key name of the indexed field
491:             * @exception StorageError(CLASS_NOT_FOUND) exception is thrown if there is no table corresponding to 
492:             * the specified class
493:             * @return <code>true</code> if record is included in index, <code>false</code> if 
494:             * there is no such index
495:             */
496:            public boolean includeInIndex(IPersistent record, String key) {
497:                return includeInIndex(record.getClass(), record, key);
498:            }
499:
500:            /**
501:             * Include record in the specified index. This method is needed to perform update of indexed
502:             * field (key). Before updating the record, it is necessary to exclude it from indices
503:             * which keys are affected using excludeFromIndex method. After updating the field, record should be 
504:             * reinserted in these indices using this method.<P>
505:             * If there is not table associated with class of this object, then 
506:             * database will search for table associated with superclass and so on...<P>
507:             * This method does nothing if there is no index for the specified field.
508:             * @param table class corresponding to the table
509:             * @param record object to be excluded from the specified index
510:             * @param key name of the indexed field
511:             * @exception StorageError(CLASS_NOT_FOUND) exception is thrown if there is no table corresponding to 
512:             * the specified class
513:             * @return <code>true</code> if record is included in index, <code>false</code> if 
514:             * there is no such index
515:             */
516:            public boolean includeInIndex(Class table, IPersistent record,
517:                    String key) {
518:                Table t = locateTable(table, true);
519:                FieldIndex index = (FieldIndex) t.indicesMap.get(key);
520:                if (index != null) {
521:                    index.put(record);
522:                    return true;
523:                }
524:                return false;
525:            }
526:
527:            /**
528:             * Select record from specified table
529:             * @param table class corresponding to the table
530:             * @param predicate search predicate
531:             * @exception StorageError(CLASS_NOT_FOUND) exception is thrown if there is no table corresponding to 
532:             * the specified class
533:             * @return iterator through selected records. This iterator doesn't support remove() method
534:             * @exception CompileError exception is thrown if predicate is not valid JSQL exception
535:             * @exception JSQLRuntimeException exception is thrown if there is runtime error during query execution
536:             */
537:            public <T extends IPersistent> IterableIterator<T> select(
538:                    Class table, String predicate) {
539:                return select(table, predicate, false);
540:            }
541:
542:            /**
543:             * Select record from specified table
544:             * @param table class corresponding to the table
545:             * @param predicate search predicate
546:             * @param forUpdate <code>true</code> if records are selected for update - in this case exclusive lock is set 
547:             * for the table to avoid deadlock.
548:             * @exception StorageError(CLASS_NOT_FOUND) exception is thrown if there is no table corresponding to 
549:             * the specified class
550:             * @return iterator through selected records. This iterator doesn't support remove() method
551:             * @exception CompileError exception is thrown if predicate is not valid JSQL exception
552:             * @exception JSQLRuntimeException exception is thrown if there is runtime error during query execution
553:             */
554:            public <T extends IPersistent> IterableIterator<T> select(
555:                    Class table, String predicate, boolean forUpdate) {
556:                Query q = prepare(table, predicate, forUpdate);
557:                return q.execute(getRecords(table));
558:            }
559:
560:            /**
561:             * Prepare JSQL query. Prepare is needed for queries with parameters. Also
562:             * preparing query can improve speed if query will be executed multiple times
563:             * (using prepare, it is compiled only once).<P>
564:             * To execute prepared query, you should use Query.execute(db.getRecords(XYZ.class)) method
565:             * @param table class corresponding to the table
566:             * @param predicate search predicate
567:             * @exception StorageError(CLASS_NOT_FOUND) exception is thrown if there is no table corresponding to 
568:             * the specified class
569:             * @exception CompileError exception is thrown if predicate is not valid JSQL exception
570:             */
571:            public <T extends IPersistent> Query<T> prepare(Class table,
572:                    String predicate) {
573:                return prepare(table, predicate, false);
574:            }
575:
576:            /**
577:             * Prepare JSQL query. Prepare is needed for queries with parameters. Also
578:             * preparing query can improve speed if query will be executed multiple times
579:             * (using prepare, it is compiled only once).<P>
580:             * To execute prepared query, you should use Query.execute(db.getRecords(XYZ.class)) method
581:             * @param table class corresponding to the table
582:             * @param predicate search predicate
583:             * @param forUpdate <code>true</code> if records are selected for update - in this case exclusive lock is set 
584:             * for the table to avoid deadlock.
585:             * @exception StorageError(CLASS_NOT_FOUND) exception is thrown if there is no table corresponding to 
586:             * the specified class
587:             * @exception CompileError exception is thrown if predicate is not valid JSQL exception
588:             */
589:            public <T extends IPersistent> Query<T> prepare(Class table,
590:                    String predicate, boolean forUpdate) {
591:                Table t = locateTable(table, forUpdate, false);
592:                Query q = storage.createQuery();
593:                q.prepare(table, predicate);
594:                if (t != null) {
595:                    Iterator iterator = t.indicesMap.entrySet().iterator();
596:                    while (iterator.hasNext()) {
597:                        Map.Entry entry = (Map.Entry) iterator.next();
598:                        FieldIndex index = (FieldIndex) entry.getValue();
599:                        String key = (String) entry.getKey();
600:                        q.addIndex(key, index);
601:                    }
602:                }
603:                return q;
604:            }
605:
606:            /** 
607:             * Get iterator through all table records
608:             * @param table class corresponding to the table
609:             * @return iterator through all table records.
610:             * @exception StorageError(CLASS_NOT_FOUND) exception is thrown if there is no table corresponding to 
611:             * the specified class
612:             */
613:            public <T extends IPersistent> IterableIterator<T> getRecords(
614:                    Class table) {
615:                return getRecords(table, false);
616:            }
617:
618:            /** 
619:             * Get iterator through all table records
620:             * @param table class corresponding to the table
621:             * @param forUpdate <code>true</code> if records are selected for update - in this case exclusive lock is set 
622:             * for the table to avoid deadlock.
623:             * @return iterator through all table records.
624:             * @exception StorageError(CLASS_NOT_FOUND) exception is thrown if there is no table corresponding to 
625:             * the specified class
626:             */
627:            public <T extends IPersistent> IterableIterator<T> getRecords(
628:                    Class table, boolean forUpdate) {
629:                Table t = locateTable(table, forUpdate, false);
630:                return new IteratorWrapper<T>(t == null ? new LinkedList<T>()
631:                        .iterator() : t.extent.iterator());
632:            }
633:
634:            /**
635:             * Get storage associated with this database
636:             * @return underlying storage
637:             */
638:            public Storage getStorage() {
639:                return storage;
640:            }
641:
642:            static class Table extends Persistent {
643:                IPersistentSet extent;
644:                Link indices;
645:
646:                transient HashMap indicesMap = new HashMap();
647:
648:                public void onLoad() {
649:                    for (int i = indices.size(); --i >= 0;) {
650:                        FieldIndex index = (FieldIndex) indices.get(i);
651:                        indicesMap
652:                                .put(index.getKeyFields()[0].getName(), index);
653:                    }
654:                }
655:            }
656:
657:            HashMap tables;
658:            Storage storage;
659:            Index metadata;
660:            boolean multithreaded;
661:            boolean autoRegisterTables;
662:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.