Comparing two IFS objects just became much simpler with the new COMPARE_IFS service.
The COMPARE_IFS table function allows you to compare two IFS objects and determine if the objects being compared have different attributes. You can also compare the contents of two different directories and determine whether there are objects that exist in one directory and not the other and whether those objects in the directory and its subdirectories have different attributes.
These are the table function’s parameters:
- The paths of both objects you wish to compare: You can compare objects on the same partition, or, if you choose, on the second path name. You can also specify a relational database (RDB) name, allowing you to compare the object on the current partition with one on another partition.
- The type of objects that you would like to compare: Supported types that can be compared are *CHRSF, *DIR, *FIFO, *SOCKET, *STMF, and *SYMLINK objects. The default value is *ALL, which will compare all supported object types.
- If the object is a directory, you can also set parameters that determine
- whether or not you want to recursively compare all objects in any subdirectories
- whether you would like to compare the attributes of the objects or just the names of the objects.
Let’s look at some examples. First, we will create a directory with three *STMFs in it and save and restore this directory into a backup directory.
-- ***************************************************************
-- Create a directory with four stream files in the directory.
-- ***************************************************************
-- Make the directory
CL: MKDIR DIR('/home/TestDirectory');
-- Create the files in the directory
CALL IFS_WRITE(PATH_NAME => '/home/TestDirectory/test1.txt',
LINE => 'My test data 1');
CALL IFS_WRITE(PATH_NAME => '/home/TestDirectory/test2.txt',
LINE => 'My test data 2');
CALL IFS_WRITE(PATH_NAME => '/home/TestDirectory/test3.txt',
LINE => 'My test data3');
-- ***************************************************************
-- Save the directory. Restore it into a new backup directory
-- ***************************************************************
-- Create a library and a save file in that library
CL: CRTLIB MYLIB2;
CL: CRTSAVF MYLIB2/SAVE1;
-- Save the directory and all objects in it
CL: SAV DEV('/QSYS.LIB/MYLIB2.LIB/SAVE1.FILE')
OBJ(('/home/TestDirectory'));
-- CPC370D: 4 objects saved.
-- Restore the directory and all objects in it to TestDirectory_backup
CL:RST DEV('/QSYS.LIB/MYLIB2.LIB/SAVE1.FILE')
OBJ(('/home/TestDirectory' *INCLUDE '/home/TestDirectory_backup'));
-- CPC370F: 4 objects restored
Next, compare the two directories. Because all the objects are the same, no rows should be returned. The path name parameters are directories, so we will compare the directories and all objects in those directories. There are no subdirectories that we want to compare, so we will not request any recursive compares using the SUBTREE_DIRECTORIES parameter.
-- Compare the two directories. There are no differences, so
-- no rows are returned.
SELECT * FROM TABLE(
QSYS2.COMPARE_IFS(START_PATH_NAME1 => '/home/TestDirectory',
START_PATH_NAME2 => '/home/TestDirectory_backup',
SUBTREE_DIRECTORIES => 'NO',
COMPARE_ATTRIBUTES => 'YES'));
Figure 1: Results of COMPARE_IFS query. No rows returned.
We can now create a new file in the original directory. When we run the compare again, we will see that a new file exists only in the original directory.
-- ***************************************************************
-- Create a new *STMF in the original directory.
-- ***************************************************************
-- Create the test4.txt file in the original directory
CALL IFS_WRITE(PATH_NAME => '/home/TestDirectory/test4.txt',
LINE => 'My test data4');
-- Compare the two directories. An object exists only in the
-- original directory.
SELECT * FROM TABLE(
QSYS2.COMPARE_IFS(START_PATH_NAME1 => '/home/TestDirectory',
START_PATH_NAME2 => '/home/TestDirectory_backup',
SUBTREE_DIRECTORIES => 'NO',
COMPARE_ATTRIBUTES => 'YES'));
Figure 2: Results of COMPARE_IFS query when an object exists in one directory only.
The ATTRIBUTE_NAME column tells us that we have an unmatched path name in the directory. The VALUE1 column tells us the name of the path that exists in the first directory only.
You can also make changes to an existing file. In this example, we will change the attributes of one of the original files and one of the backup files. COMPARE_OBJECTS will report these attribute differences if the COMPARE_ATTRIBUTE parameter is set to ‘YES’.
-- ***************************************************************
-- Change objects that exist in both directories. Compare the
-- objects using COMPARE_ATTRIBUTES 'NAME' and 'YES'.
-- ***************************************************************
-- Change object in original directory
CL: CHGATR OBJ('/home/TestDirectory/test1.txt') ATR(*READONLY) VALUE(*YES);
-- Change object in backup directory
CL: CHGATR OBJ('/home/TestDirectory_backup/test2.txt')
ATR(*ALWSAV) VALUE(*NO);
SELECT * FROM TABLE(
QSYS2.COMPARE_IFS(START_PATH_NAME1 => '/home/TestDirectory',
START_PATH_NAME2 => '/home/TestDirectory_backup',
SUBTREE_DIRECTORIES => 'NO',
COMPARE_ATTRIBUTES => 'YES'));
Figure 3: Results of COMPARE_IFS query when attributes are different and compared.
The ATTRIBUTE_NAME column will tell which attributes are different. In this case, the OBJECT_READ_ONLY value is different for the first file and the ALLOW_SAVE attribute is different for the second file. The VALUE1 and VALUE2 columns tell you the value of the different attribute.
If you only want to see whether there are differences in which files exist and don’t want to do the deeper attribute check, you can change the COMPARE_ATTRIBUTE column to search only for ‘NAMES’. In the following example, we only have one row returned, not three, because we are only looking for unmatched PATH_NAMES.
SELECT * FROM TABLE(
QSYS2.COMPARE_IFS(START_PATH_NAME1 => '/home/TestDirectory',
START_PATH_NAME2 => '/home/TestDirectory_backup',
SUBTREE_DIRECTORIES => 'NO',
COMPARE_ATTRIBUTES => 'NAMES'));
Figure 4: Results of COMPARE_IFS query when attributes are different but only NAMES are compared.
You can also compare individual objects, not just directories. In this example, we will unlink the original test3.txt file and re-create it with different data. Then we will compare the file only instead of the whole directory.
-- ***************************************************************
-- Delete and re-create a file. Compare the file only.
-- ***************************************************************
-- Remove the link
CL: RMVLNK '/home/TestDirectory/test3.txt';
-- Create the file again with the same name, but different data.
CALL IFS_WRITE(PATH_NAME => '/home/TestDirectory/test3.txt',
LINE => 'New my test data3');
SELECT * FROM TABLE(
QSYS2.COMPARE_IFS(START_PATH_NAME1 => '/home/TestDirectory/test3.txt',
START_PATH_NAME2 => '/home/TestDirectory_backup/test3.txt'));
Figure 5: Results of COMPARE_IFS query when the creation timestamp is different.
Note that in addition to the creation timestamp difference, the data size is different. We cannot directly compare the data to see if it is the same, but the data size difference does give us some insight that the data is different.
The COMPARE_IFS service is available with IBM i 7.5 TR4 and enhanced with TR5 as well as IBM i 7.4 TR10 and enhanced with TR11. For more information, see https://www.ibm.com/docs/en/i/7.5?topic=services-compare-ifs-table-function.
LATEST COMMENTS
MC Press Online