* DELETEI
* DELETE.INDEX verb
* Copyright (c) 2006 Ladybridge Systems, All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
* 
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
* 
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
* 
* Ladybridge Systems can be contacted via the www.openqm.com web site.
* 
* START-HISTORY:
* 02 Nov 06  2.4-15 VOC record types now case insensitive.
* 28 Mar 05  2.1-11 Use PARSER$MFILE.
* 13 Oct 04  2.0-5 Use message handler.
* 16 Sep 04  2.0-1 OpenQM launch. Earlier history details suppressed.
* END-HISTORY
*
* START-DESCRIPTION:
*
*    DELETE.INDEX filename field...
*    DELETE.INDEX filename ALL
*
* END-DESCRIPTION
*
* START-CODE

$internal
program deletei
$catalog $DELETEI

$include keys.h
$include int$keys.h
$include parser.h
$include err.h
$include dictdict.h
$include ak_info.h


   parser = "!PARSER"

   @system.return.code = -ER$ARGS     ;* Preset for argument errors


   call @parser(PARSER$RESET, 0, @sentence, 0)
   call @parser(PARSER$GET.TOKEN, token.type, token, keyword) ;* Verb

   * Get and process file name

   dict.flag = ''
   call @parser(PARSER$MFILE, token.type, filename, keyword)
   if keyword = KW$DICT then
      dict.flag = 'DICT'
      call @parser(PARSER$MFILE, token.type, filename, keyword)
   end
   if token.type = PARSER$END then stop sysmsg(2102) ;* File name required

   * Check file exists and is a dynamic file

   open dict.flag, filename to fu else
      open dict.flag, upcase(filename) to fu else
         stop sysmsg(2019) ;* File not found
      end
      filename = upcase(filename)
   end

   if fileinfo(fu, FL$TYPE) # FL$TYPE.DH then
      stop sysmsg(2020) ;* Dynamic file required
   end

   * Collect field names and options

   delete.all = @false
   ak.list = ''
   loop
      call @parser(PARSER$GET.TOKEN, token.type, token, keyword)
   until token.type = PARSER$END
      begin case
         case keyword = KW$ALL
            if ak.list # '' then stop sysmsg(2600) ;* Cannot use ALL with field names
            delete.all = @true

         case 1
            ak.list<-1> = token
      end case
   repeat


   if not(delete.all) and ak.list = '' then
      prompt ''
      display sysmsg(2601) :  ;* Index name:
      input ak.list

      if ak.list = '' then
         @system.return.code = 0
         goto exit.delete.index
      end

      read voc.rec from @voc, ak.list else
         read voc.rec from @voc, upcase(ak.list) else
            goto not.all.keyword
         end
      end

      if upcase(voc.rec[1,1]) = 'K' and voc.rec<2> = KW$ALL then
         ak.list = ''
         delete.all = @true
      end
   end
not.all.keyword:

   * Get AK data

   ak.names = indices(fu)
   num.aks = dcount(ak.names, @fm)
   if num.aks = 0 then stop sysmsg(2603) ;* File has no indices

   dim ak.details(num.aks)
   for i = 1 to num.aks
      ak.details(i) = indices(fu, ak.names<i>)
   next i

   pathname = fileinfo(fu, FL$PATH)

   * Deletion of an AK requires that the file is not open.  There is a small
   * window of opportunity for another process to dive in and grab the file
   * while we are deleting the AK.  It is so unlikely that we don't bother
   * with any locking mechanism.  The proper solution is for dh_ak.c to
   * accept that the file is open for exclusive access.


   if not(fileinfo(fu, FL$EXCLUSIVE)) then    ;* Set exclusive access to file
      stop sysmsg(2602) ;* Cannot gain exclusive access to file
   end
   close fu                                   ;* Close it again
   i = ospath("", os$flush.cache)             ;* Wipe out the DH cache

   @system.return.code = 0

   * Scan list for AKs to delete
   
   for i = 1 to num.aks
      if not(delete.all) then
         locate ak.names<i> in ak.list<1> setting pos else continue
         del ak.list<pos>
      end

      akno = ak.details(i)<1,5>
      delete.ak pathname, akno then
         display sysmsg(2627, ak.names<i>) ;* Deleted index xx
      end else
         display sysmsg(2628, status(), ak.names<i>)  ;* Error xx deleting index xx
         @system.return.code = -ER$AKNF
      end   
   next i

   if ak.list # '' then
      loop
         display sysmsg(2604, remove(ak.list,delim)) ;* Unrecognised index name (xx)
      while delim
      repeat
   end

exit.delete.index:

   return

end

* END-CODE
