extract_open()

Purpose

Opens an extract file

Old name

#define open_extract extract_open

Syntax

void extract_open(filename, header)

Parameters

char* filename

Name of file to use in the extract

 

struct EXT_HEADER* header

Pointer to extract header structure giving extraction parameters

Description

The extract_open() function opens and prepares an extract file using the information in the extract header. The DP4 extract functions are used to sort a collection of records.

The parameter header defines a C structure named EXT_HEADER that is used to determine which fields are used, in order of precedence, in a subsequent sort.

The fields that make up the structure of an entry in the extract file are equivalent to a database record called EXTRACT. This is generated by LIBMAKE.

The struct EXT_HEADER is declared in the file dp4capi.h

To perform a sort on selected records from the database, follow the steps below:

1. Construct the header record and the corresponding extract record. Use LIBMAKE to do this automatically by including the #extract directive, as in:

#extract <field>, [<field>], … [<field>];

Each <field> corresponds to an entry in the extract file of the same name. By default, the fields are assumed to be database fields. A <field> may include a role, for example address.invoice

LIBMAKE determines the datatype, length and occurs value for each field from the database

Non-database fields can be included by adding the datatype, length and occurs values after the field name separated by colons, for example address:c:4:16. You can leave out some of these values as there are defaults, so value:n corresponds to a double-precision value. LIBMAKE issues an error message if you attempt to specify a database field with this notation

2. Define the sort required by using the LIBMAKE directive #sorton, as below:

#sorton <field>, [<field>], … [<field>];

This gives the list of fields in the extract file on which to sort, in order of precedence, starting with the highest

3. Call the function extract_open() to open an extract file. LIBMAKE normally generates this call in the function init

4. Write records to the extract file by assigning the required fields to the extract record and calling the function extract_write()

5. Call the function extract_sort() to sort the collection of records

6. If the sort is successful, read each of the records in turn by calling the function extract_read()

7. The actual sorting of records is done by the DP4 SORTEXR program which is called by the function extract_sort(). SORTEXR is called when the function trm_run_program() is called with the parameter batch set to FALSE and the copy_screen parameter set to TRUE. You may wish the copy_screen parameter to be FALSE, in which case you should write your own version of extract_sort() as shown in the example below

See also

extract_write(), extract_sort(), extract_read()

Example

/*
 C Functions Reference Manual
 ----------------------------
 Filename: EXTRCT_O.C
 Example: extract_open
 Purpose: simple report of order headers for a
          customer ordered by delivery data.
*/

/*
#db salesord
#c
#libtype 1
#tables customer,
        order_header;
#extract order_number,
         delivery_date,
         order_value,
         payment_value;
#sorton delivery_date;
#end
*/

/*
 Run 'libmake extrct_o.c' to generate the file
 extrct_o.h containing the definition of struct
 EXTRACT and initialisation of ext_header. We don't
 want to display any details of extract while the
 sort is being done so add to the init function:
 ext_header.suppress_output = TRUE;
*/

#include "dp4.h"
#include "open_ext.h"
 /* generate this file by running LIBMAKE */

 /* prototypes */
static void get_orders(void);
static int do_sort(struct EXT_HEADER*,char*);
void process()
{
   /* get a customer number */
   map_draw(1,RETAIN);
   map_draw(2,RETAIN);
   for (;;)
   {
      if (askf_n(2,1,&customer.customer_number))
        break;
        /* need to check valid customer */
      if (rec_fetch_main(EQUAL,&customer.l))
      {
         get_orders();
         break;
      }
      else map_remark(3);
   }
}

static void get_orders()
 /* get and sort details */
{
   /* extract_open("EXTRACT",&ext_header) has
    already been called by the init function */
   int count = 0;
   int srch = FIRST_BUT;
   /* fetch all orders of the customer */
   order_header.customer_number =
              customer.customer_number;
   while (ftch2nd(srch,&order_header.l,
               &customer.l,""))
   {
      srch = NEXT_BUT;
      count++;
      /* add to the extract file */
      extract.order_number = order_header.
                 order_number;
      extract.delivery_date = order_header.
                 delivery_date;
      extract.order_value = order_header.
                 order_value;
      extract.payment_value = order_header.
                 payment_value;
      extract_write(&extract.l);
   }

     /* check for no orders */
   if (!count)
   {
      map_pause(4);
      return;
   }
   if (!do_sort(&ext_header,"EXTRACT"))
   {
       /* something went wrong*/
      map_pause(7);
      return;
   }   /* fine - do report */
   if (dvc_choose(PRINTER|SCREEN,0,"","") != ESCAPE)
   {
      form(5);
      prnc(5,1,customer.name,DEFAULT);
      prnn(5,2,customer.customer_number,DEFAULT);
      while (!read_extract(&extract.l))
      {
         form(6);
         prnl(6,1,extract.order_number,DEFAULT);
         prnn(6,2,extract.order_value,DEFAULT);
         prnn(6,3,extract.payment_value,DEFAULT);
         prnd(6,4,&extract.delivery_date,DEFAULT);
         prn_print(FALSE);
      }
   }
}

static int do_sort(ext_header, filename)
  struct EXT_HEADER* ext_header;
  char* filename;
{
   return extract_sort();
   /* On MS-DOS you might decide to write your own version of extract_sort() as below,
      but it would probably be best just to modify the code in ccextrct.c */
#if 0
   char command[80];
   int fd;
   extract_close();
   strcpy(command,"sortextr ");
   strcpy(command+strlen(command),filename);
   trm_run_program(command,FALSE,FALSE);

   /* reopen file and check header */
   if ((fd = tf_open(filename,VF_RW|VF_SEQ|VF_RET))
              < 0) return (FALSE);
   tf_read(fd,ext_header,sizeof(struct EXT_HEADER));
   tf_close(fd);
   return ext_header->sorted;
#endif
}