ekgc |
Table of contents
ProcedureEKGC ( EK, get event data, character ) ENTRY EKGC ( SELIDX, ROW, ELMENT, CDATA, NULL, FOUND ) AbstractReturn an element of an entry in a column of character type in a specified row. Required_ReadingEK KeywordsASSIGNMENT EK DeclarationsINTEGER SELIDX INTEGER ROW INTEGER ELMENT CHARACTER*(*) CDATA LOGICAL NULL LOGICAL FOUND Brief_I/OVARIABLE I/O DESCRIPTION -------- --- -------------------------------------------------- SELIDX I Index of parent column in SELECT clause. ROW I Row to fetch from. ELMENT I Index of element, within column entry, to fetch. CDATA O Character string element of column entry. NULL O Flag indicating whether column entry was null. FOUND O Flag indicating whether column was present in row. Detailed_InputSELIDX is the SELECT clause index of the column to fetch from. ROW is the output row containing the entry to fetch from. ELMENT is the index of the element of the column entry to fetch. The normal range of ELMENT is from 1 to the size of the column's entry, but ELMENT is allowed to exceed the number of elements in the column entry; if it does, FOUND is returned .FALSE. This allows the caller to read data from the column entry in a loop without checking the number of available elements first. Null values in variable-sized columns are considered to have size 1. Detailed_OutputCDATA is the requested element of the specified column entry. If the entry is null, CDATA is undefined. If CDATA is too short to accommodate the requested column entry element, the element is truncated on the right to fit CDATA. If CDATA is longer than the element, CDATA is returned blank-padded on the right. NULL is a logical flag indicating whether the entry belonging to the specified column in the specified row is null. FOUND is a logical flag indicating whether the specified element was found. If the element does not exist, FOUND is returned .FALSE. ParametersNone. Exceptions1) If the input argument ELMENT is less than 1, the error SPICE(INVALIDINDEX) is signaled and FOUND is returned .FALSE. However, ELMENT is allowed to be greater than the number of elements in the specified column entry; this allows the caller to read data from the column entry in a loop without checking the number of available elements first. If ELMENT is greater than the number of available elements, FOUND is returned .FALSE. 2) If SELIDX is outside of the range established by the last query passed to EKSRCH, the error SPICE(INVALIDINDEX) is signaled and FOUND is returned .FALSE. 3) If the input argument ROW is less than 1 or greater than the number of rows matching the query, the error SPICE(INVALIDINDEX) is signaled and FOUND is returned .FALSE. 4) If the specified column does not have character type, the error SPICE(INVALIDTYPE) is signaled. 5) If this routine is called when no E-kernels have been loaded, the error SPICE(NOLOADEDFILES) is signaled. FilesSee the header of EKQMGR for a description of files used by this routine. ParticularsThis routine allows retrieval of data from character columns. This routine returns one element at a time in order to save the caller from imposing a limit on the size of the column entries that can be handled. ExamplesThe numerical results shown for these examples may differ across platforms. The results depend on the SPICE kernels used as input, the compiler and supporting libraries, and the machine specific arithmetic implementation. 1) Perform a query on an EK file that contains a database with the Supplementary Engineering Data Records of the Viking Project in order to retrieve the IMAGE_ID values (character strings) that correspond to the images with IMAGE_NUMBER smaller than a given value, ordered by IMAGE_NUMBER. Use the EK kernel below to load the information from the original Supplementary Engineering Data Record (SEDR) data set generated by the Viking Project. vo_sedr.bdb Example code begins here. PROGRAM EKGC_EX1 IMPLICIT NONE C C Include the EK Maximum length of an input query, C MAXQRY, and the maximum length of literal string C values, MAXSTR, from eklimit.inc. C INCLUDE 'ekqlimit.inc' C C Local parameters C CHARACTER*(*) EKNAME PARAMETER ( EKNAME = 'vo_sedr.bdb' ) INTEGER ERRLEN PARAMETER ( ERRLEN = 1840 ) C C Local variables C CHARACTER*(MAXSTR) CDATA CHARACTER*(ERRLEN) ERRMSG CHARACTER*(MAXQRY) QUERY INTEGER ELTIDX INTEGER NMROWS INTEGER ROWNO INTEGER SELIDX LOGICAL ERROR LOGICAL FOUND LOGICAL ISNULL C C Open an EK file. C CALL FURNSH ( EKNAME ) C C The table 'VIKING_SEDR_DATA' has a column 'IMAGE_ID' C of scalar strings. C C Define a set of constraints to perform a query on C all loaded EK files (the SELECT clause). In this C case select the column 'IMAGE_ID' from table C 'VIKING_SEDR_DATA' sorted by 'IMAGE_NUMBER'. C QUERY = 'Select IMAGE_ID from VIKING_SEDR_DATA ' . // 'where IMAGE_NUMBER < 25860000 ' . // 'order by IMAGE_NUMBER' C C Query the EK system for data rows matching the C SELECT constraints. C CALL EKFIND ( QUERY, NMROWS, ERROR, ERRMSG ) C C Check whether an error occurred while processing the C SELECT clause. If so, output the error message. C IF ( ERROR ) THEN WRITE(*,*) 'SELECT clause error: ', ERRMSG ELSE C C Fetch the character data. We know the query returned C one column and the column contains only scalar data, C so the index of all elements is 1. C SELIDX = 1 ELTIDX = 1 C C Loop over each row found matching the query. C DO ROWNO = 1, NMROWS C C Use EKGC to retrieve the string from C CALL EKGC ( SELIDX, ROWNO, ELTIDX, . CDATA, ISNULL, FOUND ) IF ( ISNULL ) THEN WRITE (*,'(A,I3,A)') 'Row ', ROWNO, . ': Character data: <Null>' ELSE WRITE (*,'(A,I3,2A)') 'Row ', ROWNO, . ': Character data: ', CDATA END IF END DO END IF END When this program was executed on a Mac/Intel/gfortran/64-bit platform, the output was: Row 1: Character data: 168C09 Row 2: Character data: 168C10 Row 3: Character data: 168C11 Row 4: Character data: 168C12 Row 5: Character data: 169C01 Row 6: Character data: 169C02 Row 7: Character data: 169C03 Row 8: Character data: 169C04 Row 9: Character data: 169C05 Row 10: Character data: 169C09 Row 11: Character data: 169C11 Row 12: Character data: 169C19 Row 13: Character data: 169C23 Row 14: Character data: 169C25 Row 15: Character data: 169C26 Row 16: Character data: 169C30 Row 17: Character data: 169C32 Row 18: Character data: 169C33 Row 19: Character data: 169C37 Row 20: Character data: 169C39 Row 21: Character data: 169C40 Row 22: Character data: 169C44 Row 23: Character data: 169C46 Row 24: Character data: 169C47 Row 25: Character data: 169C51 Row 26: Character data: 169C53 2) This example demonstrates how to fetch string values from a column in three different cases: single values, variable-size arrays and static-size arrays. Create an EK that contains a table TAB that has the following columns: Column name Data Type Size ----------- --------- ---- CHR_COL_1 CHR 1 CHR_COL_2 CHR VARIABLE CHR_COL_3 CHR 3 Issue the following query QUERY = 'SELECT CHR_COL_1, CHR_COL_2, CHR_COL_3 FROM TAB' to fetch and dump column values from the rows that satisfy the query. Example code begins here. PROGRAM EKGC_EX2 IMPLICIT NONE C C Include the EK Column Name Size (CNAMSZ) C and EK Query Limit Parameters (MAXQRY) C INCLUDE 'ekcnamsz.inc' INCLUDE 'ekqlimit.inc' C C SPICELIB functions C INTEGER RTRIM C C Local parameters C CHARACTER*(*) EKNAME PARAMETER ( EKNAME = 'ekgc_ex2.bdb' ) CHARACTER*(*) TABLE PARAMETER ( TABLE = 'TAB' ) INTEGER CHRSLN PARAMETER ( CHRSLN = 3 ) INTEGER COL3SZ PARAMETER ( COL3SZ = 3 ) INTEGER DECLEN PARAMETER ( DECLEN = 200 ) INTEGER ERRLEN PARAMETER ( ERRLEN = 1840 ) INTEGER MXC2SZ PARAMETER ( MXC2SZ = 8 ) INTEGER NAMLEN PARAMETER ( NAMLEN = 40 ) INTEGER NCOLS PARAMETER ( NCOLS = 3 ) INTEGER NROWS PARAMETER ( NROWS = 4 ) INTEGER STRSIZ PARAMETER ( STRSIZ = 30 ) C C Local variables C CHARACTER*(DECLEN) CDECLS ( NCOLS ) CHARACTER*(CNAMSZ) CNAMES ( NCOLS ) CHARACTER*(STRSIZ) COL1 CHARACTER*(CHRSLN) COL2 ( MXC2SZ ) CHARACTER*(CHRSLN) COL3 ( COL3SZ ) CHARACTER*(STRSIZ) CVALS ( MXC2SZ ) CHARACTER*(ERRLEN) ERRMSG CHARACTER*(NAMLEN) IFNAME CHARACTER*(MAXQRY) QUERY INTEGER ELTIDX INTEGER HANDLE INTEGER I INTEGER J INTEGER NELT INTEGER NMROWS INTEGER NRESVC INTEGER RECNO INTEGER ROW INTEGER SEGNO INTEGER SELIDX LOGICAL ERROR LOGICAL FOUND LOGICAL ISNULL C C Open a new EK file. For simplicity, we will not C reserve any space for the comment area, so the C number of reserved comment characters is zero. C The variable IFNAME is the internal file name. C NRESVC = 0 IFNAME = 'Test EK/Created 13-JUN-2019' CALL EKOPN ( EKNAME, IFNAME, NRESVC, HANDLE ) C C Set up the column names and declarations C for the TAB segment. We'll index all of C the columns. C CNAMES(1) = 'CHR_COL_1' CDECLS(1) = 'DATATYPE = CHARACTER*(*), ' // . 'INDEXED = TRUE' CNAMES(2) = 'CHR_COL_2' CDECLS(2) = 'DATATYPE = CHARACTER*(3), ' // . 'SIZE = VARIABLE' CNAMES(3) = 'CHR_COL_3' CDECLS(3) = 'DATATYPE = CHARACTER*(3), ' // . 'SIZE = 3' C C Start the segment. C CALL EKBSEG ( HANDLE, TABLE, NCOLS, . CNAMES, CDECLS, SEGNO ) C C At the records to the table. C DO I = 1, NROWS C C Append a new record to the EK. C CALL EKAPPR ( HANDLE, SEGNO, RECNO ) C C Add CHR_COL_1 C CALL REPMI ( 'Column #2 has $ elements.', . '$', I*2, COL1 ) CALL EKACEC ( HANDLE, SEGNO, RECNO, . CNAMES(1), 1, COL1, .FALSE. ) C C Add I*2 items to CHR_COL_2 C DO J = 1, I*2 CALL INTSTR( J + I*100, COL2(J) ) END DO CALL EKACEC ( HANDLE, SEGNO, RECNO, . CNAMES(2), I*2, COL2, .FALSE. ) C C Add 3 items to CHR_COL_3 C DO J = 1, 3 CALL INTSTR( I + J*100, COL3(J) ) END DO CALL EKACEC ( HANDLE, SEGNO, RECNO, . CNAMES(3), 3, COL3, .FALSE. ) END DO C C Close the file. C CALL EKCLS ( HANDLE ) C C Open the created file. Perform the query and show the C results. C CALL FURNSH ( EKNAME ) QUERY = 'SELECT CHR_COL_1, CHR_COL_2, CHR_COL_3 FROM TAB' C C Query the EK system for data rows matching the C SELECT constraints. C CALL EKFIND ( QUERY, NMROWS, ERROR, ERRMSG ) C C Check whether an error occurred while processing the C SELECT clause. If so, output the error message. C IF ( ERROR ) THEN WRITE(*,*) 'SELECT clause error: ', ERRMSG ELSE DO ROW = 1, NMROWS WRITE(*,*) ' ' WRITE(*,'(A,I3)') 'ROW = ', ROW C C Fetch values from column CHR_COL_1. Since C CHR_COL_1 was the first column selected, the C selection index SELIDX is set to 1. C SELIDX = 1 ELTIDX = 1 CALL EKGC ( SELIDX, ROW, ELTIDX, . CVALS(1), ISNULL, FOUND ) IF ( ISNULL ) THEN WRITE(*,*) ' COLUMN = CHR_COL_1: <Null>' ELSE WRITE(*,*) ' COLUMN = CHR_COL_1: ', CVALS(1) END IF C C Fetch values from column CHR_COL_2 in the current C row. Since CHR_COL_2 contains variable-size array C elements, we call EKNELT to determine how many C elements to fetch. C SELIDX = 2 CALL EKNELT ( SELIDX, ROW, NELT ) ELTIDX = 1 ISNULL = .FALSE. DO WHILE ( ( ELTIDX .LE. NELT ) . .AND. ( .NOT. ISNULL ) ) CALL EKGC ( SELIDX, ROW, ELTIDX, . CVALS(ELTIDX), ISNULL, FOUND ) ELTIDX = ELTIDX + 1 C C If the column entry is null, we'll be kicked C out of this loop after the first iteration. C END DO IF ( ISNULL ) THEN WRITE(*,*) ' COLUMN = CHR_COL_2: <Null>' ELSE WRITE(*,*) ' COLUMN = CHR_COL_2: ', . ( CVALS(I)(:RTRIM(CVALS(I))) //' ', . I = 1, NELT ) END IF C C Fetch values from column CHR_COL_3 in the current C row. We need not call EKNELT since we know how C many elements are in each column entry. C SELIDX = 3 ELTIDX = 1 ISNULL = .FALSE. DO WHILE ( ( ELTIDX .LE. COL3SZ ) . .AND. ( .NOT. ISNULL ) ) CALL EKGC ( SELIDX, ROW, ELTIDX, . CVALS(ELTIDX), ISNULL, FOUND ) ELTIDX = ELTIDX + 1 END DO IF ( ISNULL ) THEN WRITE(*,*) ' COLUMN = CHR_COL_3: <Null>' ELSE WRITE(*,*) ' COLUMN = CHR_COL_3: ', . ( CVALS(I)(:RTRIM(CVALS(I))) //' ', . I = 1, COL3SZ ) END IF END DO C C We either parsed the SELECT clause or had an error. C END IF END When this program was executed on a Mac/Intel/gfortran/64-bit platform, the output was: ROW = 1 COLUMN = CHR_COL_1: Column #2 has 2 elements. COLUMN = CHR_COL_2: 101 102 COLUMN = CHR_COL_3: 101 201 301 ROW = 2 COLUMN = CHR_COL_1: Column #2 has 4 elements. COLUMN = CHR_COL_2: 201 202 203 204 COLUMN = CHR_COL_3: 102 202 302 ROW = 3 COLUMN = CHR_COL_1: Column #2 has 6 elements. COLUMN = CHR_COL_2: 301 302 303 304 305 306 COLUMN = CHR_COL_3: 103 203 303 ROW = 4 COLUMN = CHR_COL_1: Column #2 has 8 elements. COLUMN = CHR_COL_2: 401 402 403 404 405 406 407 408 COLUMN = CHR_COL_3: 104 204 304 Note that after run completion, a new EK file exists in the output directory. 3) See $Examples in EKQMGR. In this example, the names and data types of the columns from which to fetch data are not known in advance. RestrictionsNone. Literature_ReferencesNone. Author_and_InstitutionN.J. Bachman (JPL) J. Diaz del Rio (ODC Space) VersionSPICELIB Version 2.1.0, 06-JUL-2021 (JDR) Added IMPLICIT NONE statement. Edited the header to comply with NAIF standard. Added complete code examples from existing fragments. SPICELIB Version 2.0.0, 16-NOV-2001 (NJB) Bug fix: When an already loaded kernel is opened with EKOPR, it now has its link count reset to 1 via a call to EKCLS. SPICELIB Version 1.1.0, 07-JUL-1996 (NJB) Redundant CHKIN call removed from SELIDX error check. Misspelling of "issued" was fixed. Previous version line was changed from "Beta" to "SPICELIB." SPICELIB Version 1.0.0, 23-OCT-1995 (NJB) |
Fri Dec 31 18:36:18 2021