Database management system embedded in an operating system command5630114Abstract A database system embedded in an operating system command. The system is invoked by operating system commands and uses no system resources except when performing a command. Searching is performed by binary search on a sorted file and sequential search on an unsorted file. New and changed records are appended to the unsorted file and the files are merged whenever the unsorted file becomes too long. Claims We claim: Description BACKGROUND
______________________________________
struct {
char man.sub.-- id
[16];
char qfd.sub.-- id
[16];
char owner
[32];
char cost [4];
char summary
[36]
} xref.sub.-- data;
______________________________________
where xref.sub.-- data is the name of the file that contains the actual data. The command idb -f xref -s `spec*` -i cost>100 instructs idb to report any records having a key beginning with spec and having a cost greater than 100. The above record description might appear differently to a different application. For example, in another application it might be seen as follows:
______________________________________
struct {
char man.sub.-- id
[16];
char qfd.sub.-- id
[16];
miscellaneous
[72];
} xref.sub.-- data;
______________________________________
4. Maintenance The -m parameter is used to merge the main data file and the auxiliary file. The auxiliary file contains all new records inserted in the database subsequent to the creation of the database or to the last maintenance operation. The auxiliary file has the same name as the main data file, but with a prefix of a dot. During a maintenance operation, any records that have been marked as "delete" are removed from the main data file. Any records that contain duplicate keys are also removed unless the -x parameter is used. Then the auxiliary file is initialized. The -m parameter merges the auxiliary file into the main data file unconditionally. A variant, the -M parameter, performs the merge only if a certain number of records have been inserted into the auxiliary data file. For example, idb -f xref -m will merge the main and auxiliary data files unconditionally, whereas the command idb -f xref -M 20 will do the merge only if the auxiliary file has more than 20 records. The -m parameter and the variant -M are positional. If either of these parameters are inserted in the command line before one of these parameters: -a (insertion), -r or -R (replacement), -d (deletion) or -s (search), maintenance is done first and then the operation specified by the other parameter is performed. If the -m or -M parameter is inserted in the command line after one of these other parameters, the operation specified by the other parameter is done first and then maintenance is performed. With the -m parameter, one can easily dump a file and construct a new one with a different key. For example, if -xref2 has the following description:
______________________________________
struct {
char composite
[32];
miscellaneous
[72];
} xref2.sub.-- data;
______________________________________
then the command idb -f xref -s`*` .linevert split. idb -f xref2 -a -m tells the first idb to dump the contents of xref2.sub.-- data to stdout and tells the second idb to collect those data from its stdin and build xfer2.sub.-- data. 5. A Simple Application Assume as an example a company that provides telephone directory assistance. A file called directory.sub.-- data holds data respecting the local residents in the following format:
______________________________________
struct {
char last.sub.-- name
[16];
char first.sub.-- name
[16];
char phone [8];
char address
[64];
} directory.sub.-- data;
______________________________________
A value that is too long for a field will be truncated. If a value does not completely fill a field, the remainder of the field is filled with blanks. If a value is not specified at all, the entire field is filled with blanks. Search Parameter The simplest command a user can issue in idb is a simple search, such as: idb -f directory -s`*` which would result in the same list that would be obtained by using the cat command. An example of a few entries in such a list is:
______________________________________
Aardvark Bird 369-0186 110 Meadow Lane
Buffalo Bill 415-8519 2310 Prairie Dr
Fox Steve 857-0100 20 Chicken Lane
Turtle Elmer 964-2131 89 Emerald Isle Road
Weasel Sly 237-1015 312 Daisy Field Lane
Wolf Peter 674-1541 1938 Zoo Road
Wombat John B. 856-3612 2400 Tanager Ave
Wombatty S. K. 857-1236 2379 Munchkin Street
Zebra Sam 875-8900 1635 Sahara Drive
______________________________________
If a user wanted to retrieve the listings for all people whose last name starts with the letters "Wo", the command would be: idb -f directory -s `Wom*` and the resulting output would be:
______________________________________
Wombat John B. 856-3612 2400 Tanager Ave
Wombatty S. K. 857-1236 2379 Munchkin Street
______________________________________
But if the user only wanted the last name and phone number, the command would be: idb -f directory -s `Wo*` -i last.sub.-- name -i phone and the resulting output would be:
______________________________________
Wombat 856-3612
Wombatty 857-1236
______________________________________
If the same search were run, but with the further condition of retrieving only those having a prefix of 857, the command would be: idb -f directory -s `Wo*` -i "phone:857*" -i last.sub.-- name -i phone and the resulting output would be
______________________________________
Fox 857-0100
Wombat 857-1236
______________________________________
In the latter example the -i parameter was used three times. The first appearance filters the search and the second and third appearances tell idb that the output should consist of the values of the last.sub.-- name and phone fields separated by a blank. idb sends the output to stdout unless some other destination is specified. Quotation marks were used around the expression phone:857* to prevent the shell from interpreting the asterisk character. Insert Parameter There are several ways that records can be inserted. A raw record, for example only a last name and a phone number, is inserted by the following command:
______________________________________
idb -f directory -s `Flamingo
a 857-2035`
______________________________________
which does not include a first name or an address. idb will fill the "first name" and "address" fields with blanks. Items can be separated by delimiters, where a delimiter is just a metastring (that is, not part of the actual data), by the following command, where is the delimiter: idb -f directory -s `Gull Albert 723-3412 958 Catalina Lane` -a -D Delimiters may also be used to insert a partial listing, such as the listing of the preceding example, as follows: idb -f directory -s `Flamingo 857-2035` -a -D which as before will result in the "first name" and "address" fields containing blanks. If it is desired to enter a partial listing with the data in a different order than the order of the fields in the record structure, the following command can be used: idb of directory -s `857-2035 Flamingo` -a -D -i phone -i last.sub.-- name If it is desired to enter a record interactively, the command idb -f directory -a -v will result in the following prompt, in which the length of each field is displayed graphically: last.sub.-- name?. . . first.sub.-- name?. . . phone?. . . address?. . . A partial record can be entered interactively by specifying in the command parameter which fields are to be entered: idb -f directory -a -v -i phone-i last.sub.-- name In response to the preceding command, idb will prompt for only the phone number and last name. The value of one field can be specified in the command line while idb prompts for other fields. For example, the command: idb -f directory -a -v -i phone -i last.sub.-- name -i first.sub.-- name:MARY will insert the name "MARY" into the first.sub.-- name field and will prompt the user for the values of the phone and last.sub.-- name fields. Records can be copied out of one file, for example my.sub.-- file, for insertion into another file, for example directory, by the following command: cat my.sub.-- file .linevert split. idb -f directory -a or idb-f directory-a < my.sub.-- file And a filter can be used to copy only certain records from one file to another. For example, if it is desired to copy only records in which the last name starts with "S", the following command would be used: cat my.sub.-- file .linevert split. grep "S*" .linevert split. idb -f directory -a If only certain fields were to be copied, for example only last.sub.-- name and phone, the following command would be used: cat my.sub.-- file .linevert split. idb -f directory -a -i last.sub.-- name -i phone in which case the first.sub.-- name and address fields in directory would be filled with blanks. Replacement Parameter Replacement mode is similar to insertion mode. The simplest example is to change the value of one field in a record. For instance, in the telephone directory listing, to change Mr. Aardvark's first name from "Bird" to "Fowl", the following command would be used: idb -f directory -s Aardvark -R first.sub.-- name:Fowl More than one replacement can be done in one command; a plurality of replacements are evaluated left-to-right. A record can be entirely replaced with a different record. For example, to replace Mr. Aardvark's listing with a new listing for Mr. Jim Giraffe of 900 Tower Lane, the following command would be used:
______________________________________
idb -f directory -s Aardvark
r `Giraffe Jim 968-7203 900 Tower Lane`
______________________________________
Delimiters can also be used, to avoid having to indicate blank spaces, as previously described. Fields can be replaced in different order than they appear in the record structure. For example, to change the phone number and first name of Mr. Aardvark from 369-0186 to 321-7347 and from Bird to Fowl, respectively, the following command may be used: idb -f directory -s Aardvark-r `321-7347 Fowl` -a -D -R phone -R first.sub.-- name Delete Parameter The -d parameter deletes all records found by the search argument. For example, the command idb -f directory -s Aardvark -d deletes Mr. Aardvark and his phone and address from the directory. Case Insensitive Parameter The -c parameter instructs idb to disregard case. For example, the command: idb -f directory -s `aardvark` -c would return all of the following records:
______________________________________
Aardvark Bird 369-0186 110 Meadow Lane
AARDVARK Sam 368-9075 220 Green Street
aardvark Tom 456-7890 8527 Memory Drive
______________________________________
whereas the command: idb -f directory -s `aardvark` would return only the record: aardvark Tom 456-7890 8527 Memory Drive When specifying case insensitivity, it is necessary for idb to perform two binary searches of a file, one search per case of the initial character of the field being searched. This is because upper and lower case instances of the same letter are represented differently, and will appear in different locations within a file that has been sorted on that field. There may be two distinct groups of records within this sorted file, one group having all of the records beginning with the uppercase letter and the other having all of the records beginning with the lowercase letter. Thus, in the above example, there may be one or more intervening record between the AARDVARK record and the aardvark record. In such an event, the first binary search will find the record group containing the Aardvark and the AARDVARK records, but will not find the aardvark record. The second search will then be required to find the aardvark record. It is also possible that a binary search will find a record other than the first record in a group. In the previous example, it may be that the first binary search will find the AARDVARK record rather than finding the Aardvark record. Thus, when the binary search finds a record, it will push the record into a stack. Then, idb will perform a backwards serial search looking for those records that match the search argument and push them into the stack. The backwards serial search ends when no more records match the search argument or when the loop reaches the beginning of the file. It will then be possible to pop the stack to return the record on top of the stack. That is, in the previous example, the Aardvark record. This procedure will also be performed in instances where duplication of keys is permitted. Horizontal Expand Parameter The layout of records is seldom stable over time. The -y parameter allows the dynamic expansion of the file either by enlarging the size of a field or by introducing a new field. For example, to make a new entry in the above telephone directory in which the value of phone must include international dialing codes and extensions, the -y parameter can be added to an insert command as follows: idb -f directory -s `Poodle Jacques 011-36-3-20-10-56-42-89x1235 77 Rue du Cologne, Paris` -a -D -y In this example, the -y parameter will expand the phone field from 8 to 28 characters throughout the file and will modify the file description to indicate that the phone field has 28 characters. The -Y parameter is similar to the -y parameter except that -Y allows for either expansion or contraction of a field. Using the -y parameter to add new fields will be discussed in a subsequent paragraph. Retrieving a Record That Matches a Condition The -o parameter is used anytime it is desired to process only one record at a time, for example in a loop. If it is desired, say, to send a letter to all persons having an 837 prefix to their phone numbers, the following Korn Shell script could be used, including the -o parameter:
______________________________________
x=1
o $x` user=`idb -f directory -s `837-*`
do
send.sub.-- a.sub.-- letter $user
((x=x+1))
done
______________________________________
The variable x will take the values 1, 2, 3, . . . and idb will return the first, second, third . . . record that satisfies the condition -s `837=*`. Remote Access If the filename following the -f parameter includes the `@` character, idb will assume that the characters following the @ are the name of a remote host and idb will execute a remote shell on the remote host, using the parameters in the command line. For example, in response to the command: idb -f desc@remote -s `*`>result idb will execute a search on the system named remote and will leave the output of the search in the file titled result. Creation of a New Database Appropriate parameters may be used to cause idb to create a new file description and database. For example, the user may cause idb to use contents of an existing file called passwd to create the following file description:
______________________________________
struct {
char login [8];
/* offset = 0 */
char pwd [13];
/* offset = 8 */
char uid [3];
/* offset = 21 */
char gid [4];
/* offset = 24 */
char misc [27];
/* offset = 28 */
char home [21];
/* offset = 55 */
char shell [20];
/* offset = 76 */
} passwd.sub.-- data
/* record len = 96 + 1 */
______________________________________
by means of the following command: idb -f passwd -i login -i pwd -i uid -i gid -i misc -i home -i shell -a -y -D: -m<passwd where the parameters have the following meanings:
______________________________________
a a record is being added
i description of a field
y create undeclared fields
D: data will be delimited by the colon
m perform maintenance after the transaction has been
completed
______________________________________
and stdin is redirected to read from/etc/passwd. Of course, the same result could have been obtained by piping the contents of/std/passwd into idb. The user may use cat and idb to create a database called group out of the fields titled group and gid from the file passwd by means of the following command: cat group .linevert split. cut -f1,32 -d: .linevert split. idb -f group -i group -i gid -a -y -D: -m which results in the following data file:
______________________________________
adm 4
atm 21
bin 2
daemon 5
guest 1044
lp 7
mail 6
other 1
root 0
scaff 24
sys 3
users 20
wizard 10
______________________________________
The two databases described above may be joined by selecting those gid's in passwd that are not referenced in group by the following commands: idb -f passwd -s `*` -i login -I gid -D: >from.sub.-- passwd idb -f group -s `*` -i group -I gid -D: >from.sub.-- group join -1 2 -2 2 -a 2 -t: from.sub.-- passwd from.sub.-- group .linevert split. grep -v `.*:.*:.*` where the parameters of the join command mean to take the second field from both files (1 and 2); produce a line of output for each unpairable line in the file from.sub.-- group in addition to the normal output; and use the character ":" as a separator. The parameter -v of the grep command means to print all lines but those that match the pattern ".*:.*:.*". The idb parameters have the following meanings: -s means that the search argument is the wild-card character "*"; the -i parameter without an argument means that what is wanted is only the fields login and gid, not the raw record; the -I parameter is similar to -i except that the output is to be sorted by gid. The result of the above three commands is the following output:
______________________________________
0 :root
1 :other
10 :wizard
21 :atm
6 :mail
______________________________________
which means that the groups named in the output have no counterparts in passwd. The following command will replace the shell of all the users that belong to the groups 4 or 20 with the default shell/bin/ksh: idb -f passwd -s `*` -i gid:20 -I gid:4 -R shelh/bin/ksh where the -i parameter performs a logical AND to the search argument * and the paramenter -I performs a logical OR. The following command adds a new record interactively: idb -f passwd -a -v idb will prompt the user with the name of the field followed by a number of dots corresponding with the length of the field: login?. . . pdw?. . . uid?. . . gid?. . . misc?. . . home?. . . shell?. . . Entering <CNTL/D> in the first field login will stop the prompting. Entering <CNTL/D> in any other field will prompt for the previous field. If the -s parameter is not present in the command line, idb will assume that the new record(s) come from stdin. For example, in the command: idb -f passwd -a idb prompts the user with a question mark if stdin is a terminal, or idb assumes that the record(s) come from either a file or a pipe. An example of this is: idb-f passwd-a <input cat input .linevert split. grep "r*" .linevert split. idb -f passwd -a The following command will expand a data file to create a new field: idb -f passwd -s `*` -y -m -i new.sub.-- field:xxxx The -i parameter with the -y parameter instructs idb to add new.sub.-- field to the file description and to expand the entire data file with four characters (the length of the string xxxx). idb will generate a new descriptor with new.sub.-- field appended to the existing list of fields. In the case of the above file structure, the result will be:
______________________________________
struct {
char login [8];
/* offset = 0 */
char pwd [13];
/* offset = 8 */
char uid [3];
/* offset = 21 */
char gid [4];
/* offset = 24 */
char misc [27];
/* offset = 28 */
char home [21];
/* offset = 55 */
char shell [20];
/* offset = 76 */
char new.sub.-- field [4];
/* offset = 96 */
} passwd.sub.-- data
/* record len = 100 + 1 */
______________________________________
Although a specific embodiment of the invention has been described and illustrated, the invention is not to be limited to the specific forms or arrangements of parts so described and illustrated, and various modifications and changes can be made without departing from the scope and spirit of the invention. Within the scope of the appended claims, therefore, the invention may be practiced otherwise than as specifically described and illustrated.
|
Same subclass Same class Consider this |
||||||||||
