eXtropia: the open web technology company
Technology | Support | Tutorials | Development | About Us | Users | Contact Us
Development resources
 ::   WebWare 2.1 (Perl)
 ::   WebWare 2.0 (Java)
 ::   Cool hacks
radical hacks
Persistent EZDB Compatible Indices in Webstore  
sent in the following documentation...

Indices are required to locate items of importance in an information retrieval system. Managing and index requires several software features in a computer system. Obviously it is necessary to read and write the index files.

The following example returns the index named in the %index_table hash. The method assumes that $index_path and %index_table are globally declared variable locations.

###################################
#		Sub get_index		        #
###################################
sub get_index
{
my @db_row;
my @db_definition;
my $index_line='';
my $line='';

  open(INDEXVIRTUAL, "$index_path") ||
  &file_open_error("$index_path","Read Index",
  __VIRTUAL__,__LINE__);
  
  $line = ;
  @db_definition = split(/\|/,$line);
  while (!eof(INDEXVIRTUAL)) 
     {
      $line = ;		
      @db_row = split(/\|/,$line); 
      $index_table{$db_row[1]} = $db_row[2];
     }
} #end of get_index subroutine

As programmers become more structured, they tend to want to pass the variables in a consistent manner supported by the language. Thus the method could look like this:

#####################################
#		Sub get_index		        #
#####################################

sub get_index
{
local $index_path , %index_table = @_;
my @db_row;
my @db_definition;
my $index_line='';
my $line='';

  open(INDEXVIRTUAL, "$index_path") ||
  &file_open_error("$index_path","Read Index",
  __VIRTUAL__,__LINE__);
  
  $line = ;
  @db_definition = split(/\|/,$line);
  while (!eof(INDEXVIRTUAL)) 
     {
      $line = ;		
      @db_row = split(/\|/,$line); 
      $index_table{$db_row[1]} = $db_row[2];
     }
return (%index_table);
} #end of get_index subroutine

It is more apparent the values passed to it, and those returned.

If you study the method you will find that it supports the existence of an incidental header in the file, which can be used by an external program like EZDB to access data in the file. The header conveniently describes to commonly used database management utilities the fieldnames in each row of the data file.

pkey|company|value|blank	# Row 0
1000|Acme Electric|32|	# Row 1
1001|Sprites|11|		# Row 2
1002|Northern Air|16|	# Row 3

Thus the following method efficiently uses the get_index subroutine twice to initialize to indices.

##################################
#	   Sub initialize_indices   #
##################################

sub initialize_indices 
  { 
  $index_path = $categories_index_path;
  %index_table=();
  &get_index;
  %categories_index = %index_table;	
  $index_path = $companies_index_path;
  %index_table=();
  &get_index;
  %companies_index = %index_table;
  }

These methods were entirely comprised of read operations.

To update the indices with new information, the following fundamental method retains the incidental header segment, and over-writes the remainder of the file with updated information.

#############################
#	 Sub update_index       #
#############################
sub update_index
{
local ($index_path,%index_table) = @_;	
local (@db_row);
my $display_line='';
my $newline='';
my $line='';

  open (INDEXVIRTUAL, "$index_path") ||
  &file_open_error("$index_path","Reading Index",
  __VIRTUAL__,__LINE__);
  
  $line = ;
  $newline = $line; 	# Variable holds header information.

  while ()   # Contents of the hash array
                        # are read and replaced with new
                        # information before being into the
                        # $newline variable.
     {
      @db_row = ();
      $line = $_;		
      @db_row = split(/\|/,$line); 
      $db_row[2] = $index_table{$db_row[1]};
      $display_line = join "|",@db_row;
      $newline .= $display_line; 
      #print "$display_line
"; } # $newline holds entire contents of index file. close INDEXVIRTUAL; open (INDEXVIRTUAL, ">$index_path") || &file_open_error("$index_path","Writing Index", __VIRTUAL__,__LINE__); flock INDEXVIRTUAL, $EXCLUSIVE; print INDEXVIRTUAL $newline; flock INDEXVIRTUAL, $UNLOCK; close INDEXVIRTUAL; } #end of update_index subroutine

With this fundamental kernal method in hand, its easy to write methods that update indeces with new information.

##############################
#     Sub update_categories_index_values         #
##############################
sub update_categories_index_values{
$index_path = $categories_index_path;
%index_table=();
%index_table=%categories_index;
&update_index_counters;
}

##############################
#     Sub update_companies_index_values        #
##############################
sub update_companies_index_values{
$index_path = $companies_index_path;
%index_table=();
%index_table=%companies_index;
&update_index_counters;
}

Another example of fetching and updating an order number index uses the two fundamental kernal methods:

################################
#	   Sub get_order_number	       	#
################################
sub get_order_number 
  {  
  local ($index_path) = $sc_order_counter_path;
  local (%index_table) = ();
  %index_table = &get_index ($index_path);
  return %index_table;
  }

################################
#     Sub update_order_number            		#
################################
sub update_order_number {
local (%index_table) = @_;
local ($index_path) = $sc_order_counter_path;
&update_index ($index_path,%index_table);
}

The index file has the following structure:

pkey|counter|value|blank	# Row 0
1000|orders_index|32|	# Row 1

Obviously it is easy to develop new uses for indices, reading and writing them with the same fundamental methods shown. I have looked into the possibility of using the DBM module to manage the indeces shown, but have concluded that the only possible module that will support my complex data requirements (to remain compatible with remote flatfile management applications like EZDB) is the MLDBM module.

Its possible that Webstore could be re-written, supported by the MLDBM management module.

Also, if remote file management is not a requirement, then other utilities could manage the indeces described and simple DBM supported access would suffice. Development of management utilities is much easier if remote access is not a requirement at this time.