| ekacec_c |
|
Table of contents
Procedure
ekacec_c ( EK, add character data to column )
void ekacec_c ( SpiceInt handle,
SpiceInt segno,
SpiceInt recno,
ConstSpiceChar * column,
SpiceInt nvals,
SpiceInt cvalen,
const void * cvals,
SpiceBoolean isnull )
AbstractAdd data to a character column in a specified EK record. Required_ReadingEK KeywordsEK UTILITY Brief_I/OVARIABLE I/O DESCRIPTION -------- --- -------------------------------------------------- handle I EK file handle. segno I Index of segment containing record. recno I Record to which data is to be added. column I Column name. nvals I Number of values to add to column. cvalen I Declared length of character values. cvals I Character values to add to column. isnull I Flag indicating whether column entry is null. Detailed_Input
handle is the handle of an EK file open for write access.
segno is the number of the segment to which the record
is to be added. EK segment numbers range from
0 to N-1, where N is the number of segments
in the kernel.
recno is the index of the record to which data is to be
added. This record number is relative to the start
of the segment indicated by segno; the first
record in the segment has index 0.
column is the name of the column to which data is to be
added.
nvals is the number of entries in the value to be added to the
specified column.
cvalen is the length of the strings in the cvals array, where
the length includes space for null terminators.
If the column has fixed-size entries, then nvals
must equal the entry size for the specified column.
cvals is the set of values themselves. The data values are
written into the specified column and record.
The array cvals should be declared with dimensions
[nelts][cvalen]
where nelts is greater than or equal to nvals.
isnull is a logical flag indicating whether the entry is
null. If `isnull' is SPICEFALSE, the column entry
defined by `nvals' and `cvals' is added to the
specified kernel file.
If `isnull' is SPICETRUE, `nvals' and `cvals' are
ignored: no data are written into the specified
column entry. The column entry is marked as a null
value.
If the column has fixed-length, variable-size
entries, the number of entries is considered to
be 1.
Detailed_OutputNone. See -Particulars for a description of the effect of this routine. ParametersNone. Exceptions
1) If `handle' is invalid, an error is signaled by a routine in the
call tree of this routine.
2) If `segno' is out of range, an error is signaled by a routine in
the call tree of this routine.
3) If `column' is not the name of a declared column, an error
is signaled by a routine in the call tree of this routine.
4) If `column' specifies a column of whose data type is not
character, the error SPICE(WRONGDATATYPE) is signaled by a
routine in the call tree of this routine.
5) If `recno' is out of range, an error is signaled by a routine in
the call tree of this routine.
6) If the specified column has fixed-size entries and `nvals' does
not match this size, an error is signaled by a routine in the
call tree of this routine.
7) If the specified column has variable-size entries and `nvals' is
non-positive, an error is signaled by a routine in the call
tree of this routine.
8) If an attempt is made to add a null value to a column that
doesn't take null values, an error is signaled by a routine in
the call tree of this routine.
9) If `column' specifies a column of whose class is not a
character class known to this routine, the error
SPICE(NOCLASS) is signaled by a routine in the call tree of
this routine.
10) If an I/O error occurs while reading or writing the indicated
file, the error is signaled by a routine in the call tree of
this routine.
11) If the `column' input string pointer is null, the error
SPICE(NULLPOINTER) is signaled.
12) If the `column' input string has zero length, the error
SPICE(EMPTYSTRING) is signaled.
13) If the `cvals' input array pointer is null, the error
SPICE(NULLPOINTER) is signaled.
14) If the `cvals' input array strings have length less than two
characters, the error SPICE(STRINGTOOSHORT) is signaled.
15) If memory cannot be allocated to create the temporary variable
required for the execution of the underlying Fortran routine,
the error SPICE(MALLOCFAILED) is signaled.
FilesSee the EK Required Reading for a discussion of the EK file format. ParticularsThis routine operates by side effects: it modifies the named EK file by adding data to the specified record in the specified column. Data may be added to a segment in random order; it is not necessary to fill in columns or rows sequentially. Data may only be added one column entry at a time. Examples
The 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) The following program demonstrates how to create a new EK and
add data to a character column in a given record within the
file, and how to read the data from it.
Example code begins here.
/.
Program ekacec_ex1
./
#include <stdio.h>
#include <string.h>
#include "SpiceUsr.h"
int main( )
{
/.
Local parameters
./
#define EKNAME "ekacec_ex1.bdb"
#define TABLE "TABLENAME"
#define CBUFSZ 4
#define DECLEN 201
#define LINESZ 7
#define NCOLS 2
#define STRLEN 7
/.
Local variables
./
SpiceChar cdecls [NCOLS] [DECLEN];
SpiceChar cnames [NCOLS] [SPICE_EK_CSTRLN];
SpiceChar cvals [CBUFSZ][LINESZ];
SpiceChar * ifname;
SpiceInt handle;
SpiceInt i;
SpiceInt j;
SpiceInt k;
SpiceInt nresvc;
SpiceInt nvals;
SpiceInt recno;
SpiceInt segno;
SpiceBoolean isnull;
/.
Create a list of character strings.
./
SpiceChar cbuf [CBUFSZ][STRLEN] = {
"CHSTR1", "CHSTR2", "CHSTR3", "CHSTR4" };
/.
Open a new EK file. For simplicity, we will not
reserve any space for the comment area, so the
number of reserved comment characters is zero.
The variable `ifname' is the internal file name.
./
nresvc = 0;
ifname = "Test EK/created 31-MAY-2019";
ekopn_c ( EKNAME, ifname, nresvc, &handle );
/.
Define the column names and formats.
./
strcpy( cnames[0], "CCOL" );
strcpy( cdecls[0], "DATATYPE = CHARACTER*(*), "
"INDEXED = TRUE, NULLS_OK = TRUE" );
strcpy( cnames[1], "CARRAY" );
strcpy( cdecls[1], "DATATYPE = CHARACTER*(6), "
"SIZE = VARIABLE, NULLS_OK = TRUE" );
/.
Start the segment.
./
ekbseg_c ( handle, TABLE, NCOLS, SPICE_EK_CSTRLN,
cnames, DECLEN, cdecls, &segno );
/.
Append a new record to the EK.
./
ekappr_c ( handle, segno, &recno );
/.
Add the value "999" to the first record of the column
CCOL in the `segno' segment of the EK file designated
by `handle'.
./
ekacec_c ( handle, segno, recno, "CCOL",
1, 4, "999", SPICEFALSE );
/.
Add an array `cbuf' of 4 values to the first record of
the column CARRAY in the `segno' segment of the EK file
designated by `handle'.
./
ekacec_c ( handle, segno, recno, "CARRAY",
CBUFSZ, STRLEN, cbuf, SPICEFALSE );
/.
Append a second record to the EK.
./
ekappr_c ( handle, segno, &recno );
/.
Repeat the operation again for the second record, but
this time, add only 2 values of `cbuf'.
./
ekacec_c ( handle, segno, recno, "CARRAY",
2, STRLEN, cbuf, SPICEFALSE );
/.
Add a null value to the CCOL in the second record.
The argument 999 is ignored because the null flag is
set to SPICETRUE.
./
ekacec_c ( handle, segno, recno, "CCOL",
1, 4, "999", SPICETRUE );
/.
Close the file.
./
ekcls_c ( handle );
/.
Open the created file. Show the values added.
./
ekopr_c ( EKNAME, &handle );
printf( "Record CCOL CARRAY\n" );
printf( "------ ------ ------------------------------\n" );
/.
The file we have created has only one segment and
two records within. Each record has two columns.
./
segno = 0;
/.
Go over each record...
./
for ( i = 0; i < 2; i++ )
{
printf( "%4d ", i );
/.
... and each column.
./
for ( j = 0; j < NCOLS; j++ )
{
/.
Read the data from the first column.
./
ekrcec_c ( handle, segno, i, cnames[j],
LINESZ, &nvals, cvals, &isnull );
if ( isnull )
{
printf( "NULL " );
}
else
{
for ( k = 0; k < nvals; k++ )
{
printf( "%6s ", cvals[k] );
}
}
}
printf( " \n" );
}
return ( 0 );
}
When this program was executed on a Mac/Intel/cc/64-bit
platform, the output was:
Record CCOL CARRAY
------ ------ ------------------------------
0 999 CHSTR1 CHSTR2 CHSTR3 CHSTR4
1 NULL CHSTR1 CHSTR2
Note that after run completion, a new EK file exists in the
output directory.
2) A more detailed example.
Suppose we have an E-kernel which contains records of orders
for data products. The E-kernel has a table called DATAORDERS
that consists of the set of columns listed below:
DATAORDERS
Column Name Data Type
----------- ---------
ORDER_ID INTEGER
CUSTOMER_ID INTEGER
LAST_NAME CHARACTER*(*)
FIRST_NAME CHARACTER*(*)
ORDER_DATE TIME
COST DOUBLE PRECISION
The order database also has a table of items that have been
ordered. The columns of this table are shown below:
DATAITEMS
Column Name Data Type
----------- ---------
ITEM_ID INTEGER
ORDER_ID INTEGER
ITEM_NAME CHARACTER*(*)
DESCRIPTION CHARACTER*(*)
PRICE DOUBLE PRECISION
We'll suppose that the EK file contains two segments, the
first containing the DATAORDERS table and the second
containing the DATAITEMS table.
This examples demonstrates how to open a new EK file; create
the two segments described above, using fast writers; and
how to insert a new record into one of the tables.
Use the LSK kernel below to load the leap seconds and time
constants required for the conversions.
naif0012.tls
Example code begins here.
/.
Program ekacec_ex2
./
#include <string.h>
#include "SpiceUsr.h"
int main( )
{
/.
Local parameters
./
#define EKNAME "ekacec_ex2.bes"
#define TABLE "DATAORDERS"
#define DECLEN 200
#define DESCLN 80
#define FNMLEN 50
#define LNMLEN 50
#define NAMLEN 40
#define NCOLS 6
#define NROWS 9
#define UTCLEN 30
/.
Local variables
./
SpiceChar cdecls [NCOLS] [DECLEN];
SpiceChar cnames [NCOLS] [SPICE_EK_CSTRLN];
SpiceChar * descrp;
SpiceChar fnames [NROWS] [FNMLEN];
SpiceChar * ifname;
SpiceChar * itemnm;
SpiceChar lnames [NROWS] [LNMLEN];
SpiceChar odate [UTCLEN];
SpiceDouble costs [NROWS];
SpiceDouble ets [NROWS];
SpiceDouble price;
SpiceInt cstids [NROWS];
SpiceInt esize;
SpiceInt handle;
SpiceInt i;
SpiceInt id;
SpiceInt itemid;
SpiceInt nresvc;
SpiceInt ordid;
SpiceInt ordids [NROWS];
SpiceInt rcptrs [NROWS];
SpiceInt recno;
SpiceInt segno;
SpiceInt sizes [NROWS];
SpiceInt wkindx [NROWS];
SpiceBoolean isnull;
SpiceBoolean nlflgs [NROWS];
/.
Load a leapseconds kernel for UTC/ET conversion.
./
furnsh_c ( "naif0012.tls" );
/.
Open a new EK file. For simplicity, we will not
reserve any space for the comment area, so the
number of reserved comment characters is zero.
The variable `ifname' is the internal file name.
./
nresvc = 0;
ifname = "Test EK/Created 01-JUN-2019";
ekopn_c ( EKNAME, ifname, nresvc, &handle );
/.
Set up the table and column names and declarations
for the DATAORDERS segment. We'll index all of
the columns. All columns are scalar, so we omit
the size declaration. Only the COST column may take
null values.
./
strcpy( cnames[0], "ORDER_ID" );
strcpy( cdecls[0], "DATATYPE = INTEGER, INDEXED = TRUE" );
strcpy( cnames[1], "CUSTOMER_ID" );
strcpy( cdecls[1], "DATATYPE = INTEGER, INDEXED = TRUE" );
strcpy( cnames[2], "LAST_NAME" );
strcpy( cdecls[2], "DATATYPE = CHARACTER*(*), INDEXED = TRUE" );
strcpy( cnames[3], "FIRST_NAME" );
strcpy( cdecls[3], "DATATYPE = CHARACTER*(*), INDEXED = TRUE" );
strcpy( cnames[4], "ORDER_DATE" );
strcpy( cdecls[4], "DATATYPE = TIME, INDEXED = TRUE" );
strcpy( cnames[5], "COST" );
strcpy( cdecls[5], "DATATYPE = DOUBLE PRECISION, "
"INDEXED = TRUE, NULLS_OK = TRUE" );
/.
Start the segment. We presume the number of rows
of data is known in advance.
./
ekifld_c ( handle, TABLE, NCOLS, NROWS, SPICE_EK_CSTRLN,
cnames, DECLEN, cdecls, &segno, rcptrs );
/.
At this point, arrays containing data for the
segment's columns may be filled in. The names
of the data arrays are shown below.
Column Data array
"ORDER_ID" ordids
"CUSTOMER_ID" cstids
"LAST_NAME" lnames
"FIRST_NAME" fnames
"ORDER_DATE" ets
"COST" costs
./
for ( i = 0; i < NROWS; i++ )
{
id = i + 1;
ordids[i] = id;
cstids[i] = id * 100;
costs[i] = id * 100.0;
repmi_c ( "Order # Customer first name", "#",
id, FNMLEN, fnames[i] );
repmi_c ( "Order # Customer last name", "#",
id, LNMLEN, lnames[i] );
repmi_c ( "1998 Mar #", "#", id, UTCLEN, odate );
utc2et_c ( odate, ets+i );
nlflgs[i] = SPICEFALSE;
}
nlflgs[1] = SPICETRUE;
/.
The `sizes' array shown below is ignored for scalar
and fixed-size array columns, so we need not
initialize it. For variable-size arrays, the
ith element of the `sizes' array must contain the size
of the ith column entry in the column being written.
Normally, the `sizes' array would be reset for each
variable-size column.
The `nlflgs' array indicates which entries are null.
It is ignored for columns that don't allow null
values. In this case, only the COST column allows
nulls.
Add the columns of data to the segment. All of the
data for each column is written in one shot.
./
ekacli_c ( handle, segno, "ORDER_ID", ordids,
sizes, nlflgs, rcptrs, wkindx );
ekacli_c ( handle, segno, "CUSTOMER_ID", cstids,
sizes, nlflgs, rcptrs, wkindx );
ekaclc_c ( handle, segno, "LAST_NAME", LNMLEN,
lnames, sizes, nlflgs, rcptrs, wkindx );
ekaclc_c ( handle, segno, "FIRST_NAME", FNMLEN,
fnames, sizes, nlflgs, rcptrs, wkindx );
ekacld_c ( handle, segno, "ORDER_DATE", ets,
sizes, nlflgs, rcptrs, wkindx );
ekacld_c ( handle, segno, "COST", costs,
sizes, nlflgs, rcptrs, wkindx );
/.
Complete the segment. The `rcptrs' array is that
returned by ekifld_c.
./
ekffld_c ( handle, segno, rcptrs );
/.
At this point, the second segment could be
created by an analogous process. In fact, the
second segment could be created at any time; it is
not necessary to populate the first segment with
data before starting the second segment.
Set up the table and column names and declarations
for the DATAITEMS segment. We'll index all of
the columns. All columns are scalar, so we omit
the size declaration.
./
strcpy( cnames[0], "ITEM_ID" );
strcpy( cdecls[0], "DATATYPE = INTEGER, INDEXED = TRUE" );
strcpy( cnames[1], "ORDER_ID" );
strcpy( cdecls[1], "DATATYPE = INTEGER, INDEXED = TRUE" );
strcpy( cnames[2], "ITEM_NAME" );
strcpy( cdecls[2], "DATATYPE = CHARACTER*(*), INDEXED = TRUE" );
strcpy( cnames[3], "DESCRIPTION" );
strcpy( cdecls[3], "DATATYPE = CHARACTER*(*), INDEXED = TRUE" );
strcpy( cnames[4], "PRICE" );
strcpy( cdecls[4], "DATATYPE = DOUBLE PRECISION, INDEXED = TRUE" );
/.
Start the new segment. Since we have no data for this
segment, start the segment by just defining the new
segment's schema.
./
ekbseg_c ( handle, "DATAITEMS", 5, SPICE_EK_CSTRLN,
cnames, DECLEN, cdecls, &segno );
/.
Close the file by a call to ekcls_c.
./
ekcls_c ( handle );
/.
Now, we want to insert a new record into the DATAITEMS
table.
Open the database for write access. This call is
made when the file already exists.
./
ekopw_c ( EKNAME, &handle );
/.
Append a new, empty record to the DATAITEMS
table. Recall that the DATAITEMS table
is in segment number 1. The call will return
the number of the new, empty record.
./
segno = 1;
ekappr_c ( handle, segno, &recno );
/.
At this point, the new record is empty. A valid EK
cannot contain empty records. We fill in the data
here. Data items are filled in one column at a time.
The order in which the columns are filled in is not
important. We use the ekaceX_c (add column entry)
routines to fill in column entries. We'll assume
that no entries are null. All entries are scalar,
so the entry size is 1.
./
isnull = SPICEFALSE;
esize = 1;
/.
The following variables will contain the data for
the new record.
./
ordid = 10011;
itemid = 531;
itemnm = "Sample item";
descrp = "This sample item is used only in tests.";
price = 1345.678;
/.
Note that the names of the routines called
correspond to the data types of the columns: the
last letter of the routine name is C, `i', or D,
depending on the data type.
./
ekacei_c ( handle, segno, recno, "ORDER_ID",
esize, &ordid, isnull );
ekacei_c ( handle, segno, recno, "ITEM_ID",
esize, &itemid, isnull );
ekacec_c ( handle, segno, recno, "ITEM_NAME",
esize, NAMLEN, itemnm, isnull );
ekacec_c ( handle, segno, recno, "DESCRIPTION",
esize, DESCLN, descrp, isnull );
ekaced_c ( handle, segno, recno, "PRICE", esize, &price, isnull );
/.
Close the file to make the update permanent.
./
ekcls_c ( handle );
return ( 0 );
}
When this program is executed, no output is presented on
screen. After run completion, a new EK file exists in the
output directory.
RestrictionsNone. Literature_ReferencesNone. Author_and_InstitutionN.J. Bachman (JPL) J. Diaz del Rio (ODC Space) Version
-CSPICE Version 1.1.0, 10-AUG-2021 (JDR)
Changed input argument name "vallen" to "cvalen" for consistency
with other routines.
Edited the header to comply with NAIF standard. Added complete
code examples.
Added entry #15 to -Exceptions section.
-CSPICE Version 1.0.0, 28-AUG-2001 (NJB)
Index_Entriesadd character data to EK column add data to EK write character data to EK column |
Fri Dec 31 18:41:05 2021