-------------------------------------------------------------------------------
-- (C) Altran Praxis Limited
-------------------------------------------------------------------------------
--
-- The SPARK toolset is free software; you can redistribute it and/or modify it
-- under terms of the GNU General Public License as published by the Free
-- Software Foundation; either version 3, or (at your option) any later
-- version. The SPARK toolset 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 distributed with the SPARK toolset; see file
-- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy of
-- the license.
--
--=============================================================================

with Heap;
with LexTokenManager;
with RelationAlgebra;
with SeqAlgebra;
with LexTokenManager.Seq_Algebra;

use type RelationAlgebra.ColLeader;
use type RelationAlgebra.Pair;
use type RelationAlgebra.RowLeader;

--# inherit Heap,
--#         LexTokenManager,
--#         LexTokenManager.Seq_Algebra,
--#         RelationAlgebra,
--#         SeqAlgebra,
--#         Statistics,
--#         SystemErrors;

--  This package extends the package RelationalAlgebra to support
--  Lex_String. This package uses case insensitive comparison betweeen
--  strings.
package LexTokenManager.Relation_Algebra is

   type Relation is private;

   procedure Create_Relation (The_Heap : in out Heap.HeapRecord;
                              R        :    out Relation);
   --# global in out Statistics.TableUsage;
   --# derives R,
   --#         The_Heap              from The_Heap &
   --#         Statistics.TableUsage from *,
   --#                                    The_Heap;

   -- Objects of type Relations utilize storage managed by the package Heap.
   -- The storage used by a relation R must be returned to the Heap  by calling
   -- DisposeOfRelation before R goes out of scope.
   procedure Dispose_Of_Relation (The_Heap : in out Heap.HeapRecord;
                                  R        : in     Relation);
   --# derives The_Heap from *,
   --#                       R;

   -- InsertPair provides the basic means to build a relation.
   -- Each pair in the relation R represented by the row value, I, and the
   -- column value J may be inserted individually.  The pair is only inserted
   -- if it is not already present.  There are no duplicates.
   procedure Insert_Pair
     (The_Heap : in out Heap.HeapRecord;
      R        : in     Relation;
      I        : in     Natural;
      J        : in     LexTokenManager.Lex_String);
   --# global in     LexTokenManager.State;
   --#        in out Statistics.TableUsage;
   --# derives Statistics.TableUsage,
   --#         The_Heap              from *,
   --#                                    I,
   --#                                    J,
   --#                                    LexTokenManager.State,
   --#                                    R,
   --#                                    The_Heap;

   -- Creates a new set S containing all the column value
   -- entries for the row of a relation R specified by GivenIndex.
   -- If a row specified by the GivenIndex is not present in R,
   -- S is the empty set.
   procedure Row_Extraction
     (The_Heap    : in out Heap.HeapRecord;
      R           : in     Relation;
      Given_Index : in     Natural;
      S           :    out Seq_Algebra.Seq);
   --# global in out Statistics.TableUsage;
   --# derives S                     from The_Heap &
   --#         Statistics.TableUsage,
   --#         The_Heap              from *,
   --#                                    Given_Index,
   --#                                    R,
   --#                                    The_Heap;

   -- AddRow adds an entire row to a relation R.
   -- The row index I is applied to each of the values in the set S to obtain
   -- a set of pairs that are added to the relation R if they are not already
   -- present in R.
   -- R and S must have been initialized using their corresponding Create ops.
   procedure Add_Row
     (The_Heap : in out Heap.HeapRecord;
      R        : in     Relation;
      I        : in     Natural;
      S        : in     Seq_Algebra.Seq);
   --# global in     LexTokenManager.State;
   --#        in out Statistics.TableUsage;
   --# derives Statistics.TableUsage,
   --#         The_Heap              from *,
   --#                                    I,
   --#                                    LexTokenManager.State,
   --#                                    R,
   --#                                    S,
   --#                                    The_Heap;

   -- AddCol adds an entire column to a relation R.
   -- The column index J is applied to each of the values in the set S to obtain
   -- a set of pairs that are added to the relation R if they are not already
   -- present in R.
   -- R and S must have been initialized using their corresponding Create ops.
   procedure Add_Col
     (The_Heap : in out Heap.HeapRecord;
      R        : in     Relation;
      J        : in     LexTokenManager.Lex_String;
      S        : in     SeqAlgebra.Seq);
   --# global in     LexTokenManager.State;
   --#        in out Statistics.TableUsage;
   --# derives Statistics.TableUsage,
   --#         The_Heap              from *,
   --#                                    J,
   --#                                    LexTokenManager.State,
   --#                                    R,
   --#                                    S,
   --#                                    The_Heap;

private

   type Relation is record
      The_Relation : RelationAlgebra.Relation;
   end record;

   function Column_Value (The_Heap : Heap.HeapRecord;
                          P        : RelationAlgebra.Pair) return LexTokenManager.Lex_String;

   function Convert_To_Relation (R : RelationAlgebra.Relation) return Relation;

   procedure Insert_Col_Leader
     (The_Heap : in out Heap.HeapRecord;
      R        : in     Relation;
      J        : in     LexTokenManager.Lex_String;
      Cache    : in out RelationAlgebra.Caches);
   --# global in     LexTokenManager.State;
   --#        in out Statistics.TableUsage;
   --# derives Cache,
   --#         The_Heap              from Cache,
   --#                                    J,
   --#                                    LexTokenManager.State,
   --#                                    R,
   --#                                    The_Heap &
   --#         Statistics.TableUsage from *,
   --#                                    Cache,
   --#                                    J,
   --#                                    LexTokenManager.State,
   --#                                    The_Heap;

end LexTokenManager.Relation_Algebra;
