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
Steve Ives
12/16/2020 9:52 PM 0
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:
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
12/16/2020 9:52 PM 0
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
12/16/2020 9:53 PM 0
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
12/16/2020 9:54 PM 0
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
12/16/2020 9:54 PM 0
Part 5: Which would produce code like this:
Anyway, hope this helps.
;;; <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
12/18/2020 5:26 PM 0
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.
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
12/25/2020 2:10 AM 0
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
12/27/2020 8:54 PM 0
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
Thanks,
Greg
12/27/2020 8:54 PM 0
Please log in to comment on this idea.