Views: We can implement views as pseudo files that actually refer to a row in a data base containing column, filter, and format specifiers for that view. To create a view: funview -p "format" -r "filter" -c "columns" view file This will make an entry into a data base having the form: view file columns filter format ---- ----------- ----------- ----------- -------------- Data base name will be the first one found: 1. getenv("FUN_VIEWBASE") 2. ./.funtools.vu 3. ~/.funtools.vu For example: funview -p "I=%3d" -r "cir 512 512 .1" -c "x y pha pi" myview snr.ev adds to database: view file columns filter format ---- ----------- ----------- ----------- -------------- myview snr.ev x y pha pi cir 512 512 .1 I=%.3d Also: funview -d view # delete view from database funview -l # list views Of course, you can edit the database file directly (but does this avoid some needed checking?) ... and we might also have a GUI ... You then use the view id instead of a file in any funtools program, prefixed by v:, i.e. fundisp v:myview funtable v:myview foo.fits The first command will run fundisp on the associated file, but using the specified filter, column, and format spec. The second runs funtable, which has no need of the print format but still utilizes the filter and column specifiers. You can override any of the three view specifiers explicitly: fundisp v:myview'[cir 400 400 1]' uses the view format and column spec, but overrides the filter, while: fundisp -f "I=%5d" v:myview'[cir 400 400 1]' "x y time" overrides everything but the file name ... probably useless but at least consistent. The syntax of a view should support templates, so that the view filter, columns, and format parameters can be used with multiple files. For example: funview -p "I=%3d" -r "cir 512 512 .1" -c "x y pha pi" myview "*.ev" adds to data base: view file columns filter format ---- ----------- ----------- ----------- -------------- myview *.ev x y pha pi cir 512 512 .1 I=%.3d You then explicitly use a template view for a file that matches the template by specifying the actual filename instead of the view: fundisp v:foo.ev Since foo.ev matches the *.ev template, this will use the myview columns, filter, and format on the foo.ev data file. Note possible conflict if a file name matches a view but ... we can avoid this to some extent by not allowing view names to contain ".", ":", "/" (same sort of restriction in xpa). A view GUI can have a selectable option to tell funtools programs always to assume a file is a view, even if v: is not prepended. This means that, if you start the GUI and select the "auto view" switch, then: fundisp v:myview and fundisp myview will be handled identically. Without the GUI running, the v: prefix will be required. There should be a way to specify which view to use for a given file: fundisp v(fi3):foo.fits means use view fi3 on file foo.fits fundisp v(reg1,col2):foo.fits means use views reg1 and col2 (in that order) on file foo.fits. Wild idea: we can implement a join of files as a view (just like the big boy databases). I think we get this for free if FunOpen just opens a pipe: pseudo file (which is implemented and might actually work) instead of a disk file. Example: we define a view called "myjoin" to be: view file ... ---- ----------- ... myjoin "funjoin -j1 key -j2 key2 cat1.fits cat2.fits" ... where the implied output arg is stdout and then we can execute: fundisp v:myjoin and get the joined result. View filters and columns would be applied to the output and it all just might work ... Good points: Explicit specification of a pseudo-file "v:[viewid]" is unambiguous and alleviates the need to rely on a separate process to prevent accident use of a view. If you don't want to use the view, just don't specify it. Easy flexibility for overriding view parameters. Support for file templates allows default setups of filter, column, and formats (can even use "*" as the file for a global setup). Uses standard funtools file type paradigm (socket:, pipe:, shm: etc). If we can implement arbitrary commands as a view file type via pipe: (particularly funjoin), then our views will be similar (superset?) to SQL views (see below). Bad points: The original idea of changing getenv would have made extensions to the list of view parameters automatic. We now have to implement each access of a view parameter explicitly, as opposed to having getenv do it automatically. Actually, this is a two-edged sword: it also could be a bad thing that each and every getenv would look for a global value. Design: I. FunOpen("v:id", ....) To process a view file spec inside FunOpen(): 1. Look for view file, either in default (~/.funtools.views) or pointed to by FUN_VIEWFILE. If it does not exist, return ERROR. 2. If filespec contains a directory character ("/") go to 4. 3. ID or simple file: Strip off and save filter spec. Look for ID name. If not found, go to 4. If found, replace input name with FILE name. If no filter spec is specified, use FILTER, otherwise use (override) filter spec. Save column spec for later use by FunColumnActivate. 4. Pathname or Simple file: Try to match file spec again template FILEs. If found, replace input name with FILE name. If no filter spec is specified, use FILTER, otherwise use (override) filter spec. Save column spec for later use by FunColumnActivate. II. FunColumnActivate(fun, columns, plist) 1. If columns != NULL, use columns (might be override). 2. If columns == NULL and fun->view_columns, use it. 3. If columns == NULL and !fun->view_columns, just return. ----------------------------------------------------------------------------- Views in SQL See: http://www.cs.unibo.it/~ciaccia/COURSES/RESOURCES/SQLTutorial/sqlch5.htm 5.2 VIEWS. (Virtual Tables and Data Security) A View, as we will see, is a definition for a "virtual table" (virtual because there is no permanent allocation of storage space) which is assembled at reference time from selected rows and/or columns of one or more real tables. A view may be queried in exactly the same way as a real table. Views are useful for two main reasons: 1) they enable users to see data, from a generalised database design, in the form most convenient for their needs. 2) they may be employed as a security mechanism for restricting user access to specific tables columns and/or rows. The statement used to create a view has the following general form: CREATE VIEW view-name [( column-list )] AS SELECT column-list FROM table-list WHERE conditional-expression ; You can display the specification of the views you have created using the help statement whose general syntax is as follows: help view view_name {,view_name} When a view is no longer required it may be dropped from the database with the DROP statement: DROP VIEW table-name ; 5.2.1 Views Designed to Simplify Queries. As we noted with Example 4.5.4, there are no direct flights from Heathrow (HROW) to Brussels (BRUS). To simplify the query required to list the departure times of interconnecting flights we will specify a view called Brussels-Link. CREATE VIEW Brussels_Link AS SELECT DISTINCT B.FlightNo,B.FromAirport, B.DepTime, B.ArrTime FROM Flight A, Flight B WHERE A.FromAirport = 'HROW' AND A.ToAirport = B.FromAirport AND B.ToAirport = 'BRUS' ; Example 5.2.1 - List the FlightNo's, Airport's, Departure and Arrival times for flights from 1500 which link Heathrow with Brussels. SELECT FromAirport, FlightNo, DepTime, ArrTime FROM Brussels_Link WHERE DepTime >= '15:00'; Result: fromai flightn deptime arrtime BIRM BD655 15:00 17:05 BIRM BD657 17:30 19:35 BIRM BD659 18:25 20:30