tips:revmedia:r95

The %FIELDS% Record

Published ByDateVersionKnowledge LevelKeywords
Revelation Technologies18 DEC 19912.1XEXPERT%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.

The layout of the %FIELDS% record is:

PosDescription
1Reserved
2Sequential counter for next positiondefault in Dictionary window.
3Field names in ascending left-justifiedorder.
4Type (F or S).
5Position.
6Btree flags. True if this field is Btreeindexed.
7Cross-reference flags. True if this fieldis Cross-reference indexed.
8Key part.
9Single or Multivalued.
10Justification.
11Display length.
12Output format.
13Default value.
14Master 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.

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:

  1. It is an F-, G-, or S-type field.
  2. The field name does not begin with the characters "%" or "@".
  3. The field has compiled successfully (F- or S-type).
  4. The field could be written successfully to the dictionary.
  5. If F-type, it has a numeric Position.
  6. If S-type, there is a formula.
  7. 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.

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.

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
  • tips/revmedia/r95.txt
  • Last modified: 2024/06/19 20:20
  • by 127.0.0.1