INTERFACE Structure

interfacename [ ( parameters ) ] := INTERFACE [ ( inherit ) ]

members;

END;

interfacenameThe ECL definition name of the interface.
parameters

Optional. The input parameters to the interface.

inheritOptional. A comma-delimited list of INTERFACE structures whose members to inherit. This may not be a passed parameter. Multiple inherited interfaces may contain attributes with the same name if they are the same type and receive the same parameters, but if those inherited members have different values defined for them, the conflict must be resolved by overriding that member in the current instance.
membersDefinitions, which may be EXPORTed or SHARED. These may be similar to fields defined in a RECORD structure where only the type and name are defined--the expression that defines the value may be left off (except in some cases where the expression itself defines the type of definition, like TRANSFORM structures). If no default value is defined for a member, any MODULE derived from the INTERFACE must define a value for that member before that MODULE can be used. These may not include other INTERFACE or abstract MODULE structures.

The INTERFACE structure defines a structured block of related members that may be passed as a single parameter to complex queries, instead of passing each attribute individually. It is similar to a MODULE structure with the VIRTUAL option, except errors are given for private (not SHARED or EXPORTed) member definitions.

An INTERFACE is an abstract structure--a concrete instance must be defined before it can be used in a query. A MODULE structure that inherits the INTERFACE and defines the values for the members creates the concrete instance for use by the query.

Example:

HeaderRec := RECORD
  UNSIGNED4 RecID;
  STRING20  company;
  STRING25  address;
  STRING25  city;
  STRING2   state;
  STRING5   zip;
END;
HeaderFile := DATASET([{1,'ABC Co','123 Main','Boca Raton','FL','33487'},
                       {2,'XYZ Co','456 High','Jackson','MI','49202'},
                       {3,'ABC Co','619 Eaton','Jackson','MI','49202'},
                       {4,'XYZ Co','999 Yamato','Boca Raton','FL','33487'},
                       {5,'Joes Eats','666 Slippery Lane','Nether','SC','12345'}
                      ],HeaderRec);

//define an interface
IHeaderFileSearch := INTERFACE
  EXPORT STRING20 company_val;
  EXPORT STRING2   state_val;
  EXPORT STRING25  city_val := '';
END;

//define a function that uses that interface
FetchAddress(IHeaderFileSearch opts) := FUNCTION
        
  //define passed values tests
  CompanyPassed := opts.company_val <> '';
  StatePassed := opts.state_val <> '';
  CityPassed := opts.city_val <> '';

   //define passed value filters
   NFilter := HeaderFile.Company = opts.company_val;
   SFilter := HeaderFile.State = opts.state_val;
   CFilter := HeaderFile.City = opts.city_val;

   //define the actual filter to use based on the passed values
   filter := MAP(CompanyPassed AND StatePassed AND CityPassed
                    => NFilter AND SFilter AND CFilter,
            CompanyPassed AND StatePassed
                    => NFilter AND SFilter ,
            CompanyPassed AND CityPassed
                    => NFilter AND CFilter,
            StatePassed AND CityPassed
                    => SFilter AND CFilter,
            CompanyPassed => NFilter ,
            StatePassed => SFilter ,
            CityPassed => CFilter,
            TRUE);
   RETURN HeaderFile(filter);
END;
        
//*****************************************************************
//then you can use the interface

InRec  := {HeaderRec AND NOT [RecID,Address,Zip]};

//this MODULE creates a concrete instance
BatchHeaderSearch(InRec l) := MODULE(IHeaderFileSearch)
  EXPORT STRING20 company_val := l.company;
  EXPORT STRING2 state_val := l.state;
  EXPORT STRING25 city_val := l.city;
END;

//that can be used like this       
FetchAddress(BatchHeaderSearch(ROW({'ABC Co','',''},InRec))); 
 
//or we can define an input dataset
InFile := DATASET([{'ABC Co','Boca Raton','FL'},
                   {'XYZ Co','Jackson','MI'},
                   {'ABC Co','',''},
                   {'XYZ Co','',''},
                   {'Joes Eats','',''}
                  ],InRec);

//and an output nested child structure
HeaderRecs := RECORD
  UNSIGNED4 Pass;
  DATASET(HeaderRec) Headers;
END;

//and allow PROJECT to run the query once for each record in InFile
HeaderRecs XF(InRec L, INTEGER C) :=  TRANSFORM
  SELF.Pass := C;
  SELF.Headers := FetchAddress(BatchHeaderSearch(L));
END;
batchHeaderLookup := PROJECT(InFile,XF(LEFT,COUNTER));
batchHeaderLookup;

See Also: MODULE Structure, LIBRARY