The %FIELDS% Record
Published By | Date | Version | Knowledge Level | Keywords |
---|---|---|---|---|
Revelation Technologies | 18 DEC 1991 | 2.1X | EXPERT | %FIELDS%, LAYOUT, DICT.MFS |
The dictionary of each file contains, as part of its control information, a record called %FIELDS%. The %FIELDS% record contains a summary of the most important characteristics of field definitions in that dictionary. This technical bulletin provides information on the layout and use of this control record.
%FIELDS% Layout
The layout of the %FIELDS% record is:
Pos | Description |
---|---|
1 | Reserved |
2 | Sequential counter for next positiondefault in Dictionary window. |
3 | Field names in ascending left-justifiedorder. |
4 | Type (F or S). |
5 | Position. |
6 | Btree flags. True if this field is Btreeindexed. |
7 | Cross-reference flags. True if this fieldis Cross-reference indexed. |
8 | Key part. |
9 | Single or Multivalued. |
10 | Justification. |
11 | Display length. |
12 | Output format. |
13 | Default value. |
14 | Master flag. True if this is the "master" definition of a field (not a synonym). |
Fields 3 through 14 are associated multivalued fields, with field 3 (field names) as the controlling field.
Maintaining %FIELDS%
The %FIELDS% control record is maintained automatically by DICT.MFS. Each time you write a record to the dictionary, DICT.MFS examines the record and determines whether it is a valid field. A field valid for inclusion in %FIELDS% must have these characteristics:
- It is an F-, G-, or S-type field.
- The field name does not begin with the characters "%" or "@".
- The field has compiled successfully (F- or S-type).
- The field could be written successfully to the dictionary.
- If F-type, it has a numeric Position.
- If S-type, there is a formula.
- If G-type, there is display information in attribute 3 of the field.
The fact that DICT.MFS enforces certain naming conventions (no "%" or "@" beginning the field name) means that these characters can only be used as prefixes in the names of dictionary control records (for example, "%SK%"). Other field name prefixes are also restricted (no "$" as a prefix, for example); although DICT.MFS does not prohibit these, other higher-level processes will fail on these types of field names.
If the %FIELDS% record does not exist, DICT.MFS builds it when first opening the dictionary. If this is happening, you will see the message "Rebuilding control records …".
If the record exists at all, DICT.MFS does not synchronize it with the existing dictionary. This leads to the possibility that %FIELDS% can be logically corrupt. For instance, this could happen if %FIELDS% were deleted, but then new dictionary records were added before DICT.MFS had an opportunity to re-open the file.
If you suspect that %FIELDS% is not up-to-date, delete the record, then re-attach the file and list the dictionary. This will cause DICT.MFS to rebuild the record. If you should ever delete the %FIELDS% record you should immediately re-attach the file.
You cannot update the %FIELDS% record yourself because it is write-protected by DICT.MFS. You will see an error to this effect if you attempt to write the record in any way.
The fact that all valid field names are maintained in %FIELDS% creates an implied limit to the size of a dictionary. All summary information about a dictionary, including all the details listed above, must fit within 64K. However, this limit is comfortably high. Assuming for a moment an average of about 35 bytes per dictionary entry, the maximum allowed would be around 1,875 fields per dictionary. Unusually long field names, formatting specifications, or default specifications would, of course, bring this number down.
Using %FIELDS%
The fact that a summary of the dictionary is maintained in a single record can come in handy during application development, mostly in the aid of speed. Examples of uses for %FIELDS% include:
- Creating quick pre-sorted listings of field names.
- Deriving field positions quickly.
- Deriving formatting specifications for reports.
- Checking index flags quickly.
Examples of different uses appear in the Figures.
Examples
Figure 1
* sorted field names in a popup DECLARE FUNCTION POP.UP FILENAME = 'SAMPLE_CUSTOMERS' AT_FIELDS = XLATE('DICT.':FILENAME,'%FIELDS%','','X') FIELD_NAMES = AT_FIELDS<3> CONVERT @VM TO @FM IN FIELD_NAMES X = 0 Y = 0 FILE = "@":FILENAME LIST = FIELD_NAMES FORMAT = "1:25:L::Field Name" ; * 1 fm-delim element per column MODE = "R" SELECT = 1 ; * single selection popup TITLE = FILENAME: " fields" ATTRIB = "" HELP = "" COORD = "1" ; * return col 1 if TYPE is null TYPE = "" ; * if null, return column in COORD @ANS=POP.UP(X,Y,FILE,LIST,FORMAT,MODE,SELECT,TITLE,ATTRIB,HELP,COORD,TYPE)
Figure 2
* use %FIELDS% to validate field names and get formatting information for a * report FILENAME = 'SAMPLE_CUSTOMERS' OPEN FILENAME TO FILE ELSE CALL FSMSG() ; STOP OPEN 'DICT.':FILENAME TO @DICT ELSE CALL FSMSG() ; STOP READ AT_FIELDS FROM @DICT,'%FIELDS%' ELSE CALL FSMSG() ; STOP FIELD_NAMES = AT_FIELDS<3> JUSTS = AT_FIELDS<10> LENGTHS = AT_FIELDS<11> * build table of fields to be displayed and their corresponding output * formats DISPLAY_FIELDS = '' DISPLAY_FORMATS = '' FIELD_CNT = 0 LOOP NEXT_FIELD = '' CALL MSG( 'Next field to display?','RC',NEXT_FIELD,'') WHILE NEXT_FIELD * validate entry LOCATE NEXT_FIELD IN FIELD_NAMES USING @VM SETTING POS THEN DISPLAY_FIELDS<-1> = NEXT_FIELD DISPLAY_FORMATS<-1> = JUSTS<1,POS> : '#' : LENGTHS<1,POS> FIELD_CNT += 1 END ELSE TEXT = NEXT_FIELD: " is not a valid field name!" CALL MSG(TEXT,'','','') END REPEAT HEADING "Report of the file: ":FILENAME: "'L'" SELECT FILE DONE = 0 LOOP READNEXT @ID ELSE DONE = 1 UNTIL DONE READ @RECORD FROM FILE, @ID THEN FOR CTR = 1 TO FIELD_CNT PRINT CALCULATE( DISPLAY_FIELDS<CTR> ) DISPLAY_FORMATS< CTR > : NEXT CTR PRINT END REPEAT
Figure 3
* simple listindex (does not include relationals) FILENAME = 'SAMPLE_CUSTOMERS' AT_FIELDS = XLATE('DICT.':FILENAME,'%FIELDS%','','X') INDEXED_FIELDS = '' COL = 0 ; CTR = 1 LOOP REMOVE NEXT_FIELD FROM AT_FIELDS<3> AT COL SETTING FLAG IF AT_FIELDS<6,CTR> OR AT_FIELDS<7,CTR> THEN INDEXED_FIELDS := NEXT_FIELD : @FM END CTR += 1 WHILE FLAG REPEAT IF INDEXED_FIELDS THEN INDEXED_FIELDS[-1,1] = '' ; * strip trailing field mark TEXT = 'Btree/Crossref indexes in ':FILENAME TEXT<-1> = INDEXED_FIELDS CALL MSG( TEXT,'','','') END ELSE TEXT = 'No fields are indexed in ':FILENAME END