Go Back
1 Vote

be able to include file paths from repository


This seems to be a glaring omission - why can't we include file paths from the repository the same way we include structures?  We are taking the time to define all the files anyway, so we should be able to utilize that information!  

.include "[structure]" repository, structure="[local variable name]"
endstructure 

why can't we do:  

.include "[file]" repository, file="[local variable name]" endfile


 

8 Comments | Posted by Greg Creme to Synergy DBL, Synergy .NET, Repository on 12/10/2020 9:40 PM
Steve Ives
Part 1, because this comment editor only allows 4000 characters!!!

I'm not sure that "glaring omission" is particularly appropriate, but I will see if I can help. I'm guessing from your proposed sample code that you want the physical file spec (e.g. DAT:customer.ism) that is associated with the repository file definition, that is associated with a repository structure definition, to be recorded in the [local variable name] variable?

If that is correct then the immediate issue would appear to be that any given repository structure can be assigned to up to 200 data file definitions, and the physical file spec of each can be up to 255 characters in length. So what would you want the variable, a comma-separated list perhaps?

But then again the presence of "endfile" suggests there is some sort of block of code to be inserted?

If my initial guess is correct, and you want to get to the array of one or more file specs associate with the structure, then you could use DDLIB to get at that information at runtime. Here's an example of how to do that:
 

12/16/2020 9:52 PM   0  
Steve Ives
Part 2: The code:
.define DDINFO_STRUCTURE
.include "RPSLIB:ddinfo.def"

;;; <summary>
;;; Given a repository structure, returns the file specs of all assigned data files.
;;; </summary>
;;; <param name="StructureName">Structure name</param>
;;; <param name="FileSpecs">Runtime array of file spec strings, each of which can be up to 256 characters.</param>
;;; <param name="ErrorMessage">Optionally returned error message</param>
;;; <returns>Returns true on success, otherwise false and an error message.</returns>
function GetStructureFileSpecs, boolean
    required in StructureName, string
    required out FileSpecs, [#]string
    optional out ErrorMessage, string
    record
        ok, boolean, true
        RpsControl, dcs
        StructureInfo, s_info
        RpsFileDefs, [200]a30
        FileInfo, fl_info
        ErrorText, string
    endrecord
proc
    xcall dd_init(RpsControl)
    if (RpsControl.error)
        freturn false

    ;Retrieve structure information for the specified structure
    xcall DD_STRUCT(RpsControl, DDS_INFO, StructureName, StructureInfo)
    if (RpsControl.error)
    begin
        ErrorText = "Structure not found!"
        ok = false
    end

    ;Does it have file assignments?
    if (ok && !StructureInfo.si_nmfils)
    begin
        ErrorText = "Structure is not assigned to any file definitions!"
        ok = false
    end

    ;Retrieve the list of files associated with the structure
    if (ok)
    begin
        data ix, int

        xcall dd_struct(RpsControl,DDS_FILS,StructureInfo.si_nmfils,RpsFileDefs)
        if (RpsControl.error)
        begin
            ErrorText = "Failed to retrieve file definition names for structure!"
            ok = false
        end

        ;Create the system array to return file specs
        FileSpecs = new string[StructureInfo.si_nmfils]

        for ix from 1 thru StructureInfo.si_nmfils
        begin
            ;Retrieve the next file definition
            xcall dd_file(RpsControl,DDL_INFO,RpsFileDefs[ix],FileInfo)
            FileSpecs[ix] = %atrimtostring(FileInfo.fli_fname)
        end
    end

    ;Close repository
    xcall dd_exit(RpsControl)

    if (^passed(ErrorMessage) && !ok)
    begin
        ErrorMessage = ErrorText
    end

    freturn ok

endfunction

 

12/16/2020 9:52 PM   0  
Steve Ives
Part 3: Here's an example of calling the function:
 
main
    record
        fileSpecs, [#]string
        errorMessage, string
    endrecord
proc
    if GetStructureFileSpecs("FRED",fileSpecs,errorMessage) then
    begin
        data ix, int
        for ix from 1 thru fileSpecs.Length
        begin
            Console.WriteLine(fileSpecs[ix])
        end
    end
    else
    begin
        Console.WriteLine("ERROR: " + errorMessage)
    end
    stop
endmain

 

12/16/2020 9:53 PM   0  
Steve Ives
Part 4: If you want a compile-time solution, because you don't have the repository available at runtime, then you can do that with CodeGen, with a template something like this:
<CODEGEN_FILENAME>Get<StructureName>FileSpecs.dbl</CODEGEN_FILENAME>
<REQUIRES_CODEGEN_VERSION>5.6.4</REQUIRES_CODEGEN_VERSION>
;;; <summary>
;;; Returns the file specs of all files assigned to structure <STRUCTURE_NAME>.
;;; </summary>
;;; <param name="FileSpecs">Runtime array of file specs or ^null if no assigned files.</param>
subroutine Get<StructureName>FileSpecs
    required out FileSpecs, [#]string
proc
    clear FileSpecs
    if (<STRUCTURE_FILES>) then
    begin
        FileSpecs = new string[<STRUCTURE_FILES>]
        <COUNTER_1_RESET>
        <FILE_LOOP>
        <COUNTER_1_INCREMENT>
        FileSpecs[<COUNTER_1_VALUE>] = "<FLOOP_NAME>"
        </FILE_LOOP>
    end
    xreturn
endsubroutine

 

12/16/2020 9:54 PM   0  
Steve Ives
Part 5: Which would produce code like this:
 
;;; <summary>
;;; Returns the file specs of all files assigned to structure CUSTOMER.
;;; </summary>
;;; <param name="FileSpecs">Runtime array of file specs or ^null if no assigned files.</param>
subroutine GetCustomerFileSpecs
    required out FileSpecs, [#]string
proc
    clear FileSpecs
    if (3) then
    begin
        FileSpecs = new string[3]
        FileSpecs[1] = "DAT:customer1.ism"
        FileSpecs[2] = "DAT:customer2.ism"
        FileSpecs[3] = "DAT:customer3.ism"
    end
    xreturn
endsubroutine

Anyway, hope this helps.
 

12/16/2020 9:54 PM   0  
Greg Creme
Hi Steve, 

I am not looking to get all the files that are used by a structure, just the path for a particular file that I know the name of.  I will review what you sent and see if I can make anything work there.  

My categorization of this as a glaring omission is that you can include a structure and enum, but not a file?  I would think that it would have made a lot of sense that if you can include a structure and enum, you should also be able to include the other types as well as a built in thing and not having to write code to do what is included out of the box for the other types of objects.  

Thank you.  

12/18/2020 5:26 PM   0  
Steve Ives
So to clarify, you want the physical file spec associated with a repository FILE definition, not a STRUCTURE definition?

12/25/2020 2:10 AM   0  
Greg Creme
Yes Steve, that is correct.  i just want the physical file spec.  We can always get the structure definition by just including the structure.  

Thanks, 
Greg

12/27/2020 8:54 PM   0  
Please log in to comment on this idea.