Source Code Cross Referenced for ViewManager.java in  » Database-DBMS » mckoi » com » mckoi » database » 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 » mckoi » com.mckoi.database 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /**
002:         * com.mckoi.database.ViewManager  20 Mar 2003
003:         *
004:         * Mckoi SQL Database ( http://www.mckoi.com/database )
005:         * Copyright (C) 2000, 2001, 2002  Diehl and Associates, Inc.
006:         *
007:         * This program is free software; you can redistribute it and/or
008:         * modify it under the terms of the GNU General Public License
009:         * Version 2 as published by the Free Software Foundation.
010:         *
011:         * This program is distributed in the hope that it will be useful,
012:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
013:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014:         * GNU General Public License Version 2 for more details.
015:         *
016:         * You should have received a copy of the GNU General Public License
017:         * Version 2 along with this program; if not, write to the Free Software
018:         * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
019:         *
020:         * Change Log:
021:         * 
022:         * 
023:         */package com.mckoi.database;
024:
025:        import java.util.HashMap;
026:        import com.mckoi.database.global.BlobAccessor;
027:        import com.mckoi.database.jdbc.SQLQuery;
028:        import com.mckoi.util.IntegerVector;
029:
030:        /**
031:         * A DatabaseConnection view manager.  This controls adding, updating, deleting,
032:         * and processing views inside the system view table.
033:         *
034:         * @author Tobias Downer
035:         */
036:
037:        public class ViewManager {
038:
039:            /**
040:             * The DatabaseConnection.
041:             */
042:            private DatabaseConnection connection;
043:
044:            /**
045:             * The context.
046:             */
047:            private DatabaseQueryContext context;
048:
049:            /**
050:             * Set to true when the connection makes changes to the view table through
051:             * this manager.
052:             */
053:            private boolean view_table_changed;
054:
055:            /**
056:             * A local cache of ViewDef objects mapped by row id in the system view
057:             * table.  This cache is invalidated when changes are committed to the system
058:             * view table.
059:             */
060:            private HashMap local_cache;
061:
062:            /**
063:             * Constructs the ViewManager for a DatabaseConnection.
064:             */
065:            ViewManager(DatabaseConnection connection) {
066:                this .connection = connection;
067:                this .context = new DatabaseQueryContext(connection);
068:                this .local_cache = new HashMap();
069:                this .view_table_changed = false;
070:
071:                // Attach a cache backed on the VIEW table which will invalidate the
072:                // connection cache whenever the view table is modified.
073:                connection.attachTableBackedCache(new TableBackedCache(
074:                        Database.SYS_VIEW) {
075:                    public void purgeCacheOfInvalidatedEntries(
076:                            IntegerVector added_rows, IntegerVector removed_rows) {
077:                        // If there were changed then invalidate the cache
078:                        if (view_table_changed) {
079:                            invalidateViewCache();
080:                            view_table_changed = false;
081:                        }
082:                        // Otherwise, if there were committed added or removed changes also
083:                        // invalidate the cache,
084:                        else if ((added_rows != null && added_rows.size() > 0)
085:                                || (removed_rows != null && removed_rows.size() > 0)) {
086:                            invalidateViewCache();
087:                        }
088:                    }
089:                });
090:
091:            }
092:
093:            /**
094:             * Returns the local cache of ViewDef objects.  This cache is mapped from
095:             * row_id to view object.  The cache is invalidated when changes are
096:             * committed to the system view table.
097:             */
098:            private HashMap getViewCache() {
099:                return local_cache;
100:            }
101:
102:            /**
103:             * Invalidates the view cache.
104:             */
105:            private void invalidateViewCache() {
106:                local_cache.clear();
107:            }
108:
109:            /**
110:             * Given the SYS_VIEW table, this returns a new table that contains the
111:             * entry with the given view name, or an empty result if the view is not
112:             * found.
113:             * Generates an error if more than 1 entry found.
114:             */
115:            private Table findViewEntry(DataTable table, TableName view_name) {
116:
117:                Operator EQUALS = Operator.get("=");
118:
119:                Variable schemav = table.getResolvedVariable(0);
120:                Variable namev = table.getResolvedVariable(1);
121:
122:                Table t = table.simpleSelect(context, namev, EQUALS,
123:                        new Expression(TObject.stringVal(view_name.getName())));
124:                t = t.exhaustiveSelect(context, Expression.simple(schemav,
125:                        EQUALS, TObject.stringVal(view_name.getSchema())));
126:
127:                // This should be at most 1 row in size
128:                if (t.getRowCount() > 1) {
129:                    throw new RuntimeException(
130:                            "Assert failed: multiple view entries for "
131:                                    + view_name);
132:                }
133:
134:                // Return the entries found.
135:                return t;
136:
137:            }
138:
139:            /**
140:             * Returns true if the view with the given name exists.
141:             */
142:            public boolean viewExists(TableName view_name) {
143:
144:                DataTable table = connection.getTable(Database.SYS_VIEW);
145:                return findViewEntry(table, view_name).getRowCount() == 1;
146:
147:            }
148:
149:            /**
150:             * Defines a view.  If the view with the name has not been defined it is
151:             * defined.  If the view has been defined then it is overwritten with this
152:             * information.
153:             *
154:             * @param view information that defines the view.
155:             * @param query the query that forms the view.
156:             * @param user the user that owns this view being defined.
157:             */
158:            public void defineView(ViewDef view, SQLQuery query, User user)
159:                    throws DatabaseException {
160:
161:                DataTableDef data_table_def = view.getDataTableDef();
162:                DataTable view_table = connection.getTable(Database.SYS_VIEW);
163:
164:                TableName view_name = data_table_def.getTableName();
165:
166:                // Create the view record
167:                RowData rdat = new RowData(view_table);
168:                rdat.setColumnDataFromObject(0, data_table_def.getSchema());
169:                rdat.setColumnDataFromObject(1, data_table_def.getName());
170:                rdat.setColumnDataFromObject(2, query.serializeToBlob());
171:                rdat.setColumnDataFromObject(3, view.serializeToBlob());
172:                rdat.setColumnDataFromObject(4, user.getUserName());
173:
174:                // Find the entry from the view that equals this name
175:                Table t = findViewEntry(view_table, view_name);
176:
177:                // Delete the entry if it already exists.
178:                if (t.getRowCount() == 1) {
179:                    view_table.delete(t);
180:                }
181:
182:                // Insert the new view entry in the system view table
183:                view_table.add(rdat);
184:
185:                // Notify that this database object has been successfully created.
186:                connection.databaseObjectCreated(view_name);
187:
188:                // Change to the view table
189:                view_table_changed = true;
190:
191:            }
192:
193:            /**
194:             * Deletes the view with the given name, or returns false if no entries were
195:             * deleted from the view table.
196:             */
197:            public boolean deleteView(TableName view_name)
198:                    throws DatabaseException {
199:
200:                DataTable table = connection.getTable(Database.SYS_VIEW);
201:
202:                // Find the entry from the view table that equal this name
203:                Table t = findViewEntry(table, view_name);
204:
205:                // No entries so return false
206:                if (t.getRowCount() == 0) {
207:                    return false;
208:                }
209:
210:                table.delete(t);
211:
212:                // Notify that this database object has been successfully dropped.
213:                connection.databaseObjectDropped(view_name);
214:
215:                // Change to the view table
216:                view_table_changed = true;
217:
218:                // Return that 1 or more entries were dropped.
219:                return true;
220:            }
221:
222:            /**
223:             * Creates a ViewDef object for the given view name in the table.  The
224:             * access is cached through the given HashMap object.
225:             * <p>
226:             * We assume the access to the cache is limited to the current thread
227:             * calling this method.  We don't synchronize over the cache at any time.
228:             */
229:            private static ViewDef getViewDef(HashMap cache,
230:                    TableDataSource view_table, TableName view_name) {
231:
232:                RowEnumeration e = view_table.rowEnumeration();
233:                while (e.hasMoreRows()) {
234:                    int row = e.nextRowIndex();
235:
236:                    String c_schema = view_table.getCellContents(0, row)
237:                            .getObject().toString();
238:                    String c_name = view_table.getCellContents(1, row)
239:                            .getObject().toString();
240:
241:                    if (view_name.getSchema().equals(c_schema)
242:                            && view_name.getName().equals(c_name)) {
243:
244:                        Object cache_key = new Long(row);
245:                        ViewDef view_def = (ViewDef) cache.get(cache_key);
246:
247:                        if (view_def == null) {
248:                            // Not in the cache, so deserialize it and put it in the cache.
249:                            BlobAccessor blob = (BlobAccessor) view_table
250:                                    .getCellContents(3, row).getObject();
251:                            // Derserialize the blob
252:                            view_def = ViewDef.deserializeFromBlob(blob);
253:                            // Put this in the cache....
254:                            cache.put(cache_key, view_def);
255:
256:                        }
257:                        return view_def;
258:                    }
259:
260:                }
261:
262:                throw new StatementException("View '" + view_name
263:                        + "' not found.");
264:
265:            }
266:
267:            /**
268:             * Creates a ViewDef object for the given index value in the table.  The
269:             * access is cached through the given HashMap object.
270:             * <p>
271:             * We assume the access to the cache is limited to the current thread
272:             * calling this method.  We don't synchronize over the cache at any time.
273:             */
274:            private static ViewDef getViewDef(HashMap cache,
275:                    TableDataSource view_table, int index) {
276:
277:                RowEnumeration e = view_table.rowEnumeration();
278:                int i = 0;
279:                while (e.hasMoreRows()) {
280:                    int row = e.nextRowIndex();
281:
282:                    if (i == index) {
283:                        Object cache_key = new Long(row);
284:                        ViewDef view_def = (ViewDef) cache.get(cache_key);
285:
286:                        if (view_def == null) {
287:                            // Not in the cache, so deserialize it and put it in the cache.
288:                            BlobAccessor blob = (BlobAccessor) view_table
289:                                    .getCellContents(3, row).getObject();
290:                            // Derserialize the blob
291:                            view_def = ViewDef.deserializeFromBlob(blob);
292:                            // Put this in the cache....
293:                            cache.put(cache_key, view_def);
294:
295:                        }
296:                        return view_def;
297:                    }
298:
299:                    ++i;
300:                }
301:                throw new Error("Index out of range.");
302:            }
303:
304:            /**
305:             * Returns a freshly deserialized QueryPlanNode object for the given view
306:             * object.
307:             */
308:            public QueryPlanNode createViewQueryPlanNode(TableName view_name) {
309:                DataTable table = connection.getTable(Database.SYS_VIEW);
310:                return getViewDef(local_cache, table, view_name)
311:                        .getQueryPlanNode();
312:            }
313:
314:            /**
315:             * Returns an InternalTableInfo object used to model the list of views
316:             * that are accessible within the given Transaction object.  This is used to
317:             * model all views as regular tables accessible within a transaction.
318:             * <p>
319:             * Note that the 'ViewManager' parameter can be null if there is no backing
320:             * view manager.  The view manager is intended as a cache to improve the
321:             * access speed of the manager.
322:             */
323:            static InternalTableInfo createInternalTableInfo(
324:                    ViewManager manager, Transaction transaction) {
325:                return new ViewInternalTableInfo(manager, transaction);
326:            }
327:
328:            // ---------- Inner classes ----------
329:
330:            /**
331:             * An object that models the list of views as table objects in a
332:             * transaction.
333:             */
334:            private static class ViewInternalTableInfo extends
335:                    AbstractInternalTableInfo2 {
336:
337:                ViewManager view_manager;
338:                HashMap view_cache;
339:
340:                ViewInternalTableInfo(ViewManager manager,
341:                        Transaction transaction) {
342:                    super (transaction, Database.SYS_VIEW);
343:                    this .view_manager = manager;
344:                    if (view_manager == null) {
345:                        view_cache = new HashMap();
346:                    } else {
347:                        view_cache = view_manager.getViewCache();
348:                    }
349:                }
350:
351:                public String getTableType(int i) {
352:                    return "VIEW";
353:                }
354:
355:                public DataTableDef getDataTableDef(int i) {
356:                    return getViewDef(view_cache,
357:                            transaction.getTable(Database.SYS_VIEW), i)
358:                            .getDataTableDef();
359:                }
360:
361:                public MutableTableDataSource createInternalTable(int i) {
362:                    throw new RuntimeException("Not supported for views.");
363:                }
364:
365:            }
366:
367:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.