/*
 * NAME
 *     print_header()   -     Spit out banner
 *     pg_init()        -     program initialization
 *
 * DESCRIPTION
 *     pg_init makes sure that the following objects exist, and creates them 
 *     if they do not not:
 *
 *     s2k_comments     class       Stores comments about database objects.
 *     s2k_get_comment  function    Returns a comment given an object name 
 *                                  and type.
 *     s2k_inherits     function    Says whether an attribute is inherited.
 *
 * FILES
 *      pg_util.c
 *
 * AUTHOR
 *      J.T. Anderson, jean@gso.saic.com
 */
#ifndef lint
static char SccsId[] = "@(#)pg_util.c	5.7 8/11/93";
#endif

#include "pg_schema.h"
#include "dd_queries.h"

#ifndef DEC
#include "assert.h"
#endif

extern dbConstr     *constr;

Proto (static dbStatus, pg_create_comment, (dbConn *dbconn));
Proto (static dbStatus, pg_create_get_comment, (dbConn *dbconn));
Proto (static dbStatus, pg_create_inherits, (dbConn *dbconn));

void
print_header(fp, str)
FILE     *fp;
char     *str;
{
     fprintf(fp,
     "/* ===============================================================\n");
     fprintf(fp, 
     " *  Create %s \n", str);
     fprintf(fp,
     " * ===============================================================\n");
     fprintf(fp, " */");
     fprintf(fp, "\n\n");
     return;
}

dbStatus
pg_init(dbconn)
dbConn *dbconn;
{

     char    *routine="pg_init";
     char    DbQuery[150];
     int     count;

     /* Does the Sequoia 2000 comments table exist? If not, create it. */

     bzero(DbQuery, sizeof(DbQuery));
     (void) strcpy(DbQuery,
     "retrieve (total = count {pg_class.oid where pg_class.relname=\"s2k_comments\"::char16 } )");

#ifndef DEC
     assert( strlen(DbQuery) < sizeof(DbQuery) );
#endif

     count = (pg_get_count (dbconn, DbQuery));
     if(count == -1)
          return(GDI_FAILURE);
     else if (count == 0)
     {
          if (pg_create_comment(dbconn) == GDI_FAILURE)
               return(GDI_FAILURE);
          if(GDI_ERROR_DEBUG(dbconn))
               fprintf(stdout, "%16s: Created class s2k_comments.\n", routine);
     }

     /* Does the comments user defined function exist? If not, create it. */

     bzero(DbQuery, sizeof(DbQuery));
     (void) strcpy(DbQuery,
     "retrieve (total = count {pg_proc.oid where pg_proc.proname=\"s2k_get_comment\"::char16 } )");

#ifndef DEC
     assert( strlen(DbQuery) < sizeof(DbQuery) );
#endif

     count = (pg_get_count (dbconn, DbQuery));
     if(count == -1)
          return(GDI_FAILURE);

     else if (count == 0)
     {    if (pg_create_get_comment(dbconn) == GDI_FAILURE)
               return(GDI_FAILURE);

          if(GDI_ERROR_DEBUG(dbconn))
               fprintf(stdout,
                    "%16s: Created user-defined function s2k_get_comment.\n",
               routine);
     }

     /* Does the s2k_inherits user defined function exist? If not, create it. */

     bzero(DbQuery, sizeof(DbQuery));
     (void) strcpy(DbQuery,
     "retrieve (total = count {pg_proc.oid where pg_proc.proname=\"s2k_inherits\"::char16 } )");

#ifndef DEC
     assert( strlen(DbQuery) < sizeof(DbQuery) );
#endif

     count = (pg_get_count (dbconn, DbQuery));
     if(count == -1)
          return(GDI_FAILURE);

     else if (count == 0)
     {    if (pg_create_inherits(dbconn) == GDI_FAILURE)
               return(GDI_FAILURE);

          if(GDI_ERROR_DEBUG(dbconn))
               fprintf(stdout,
                    "%16s: Created user-defined function s2k_inherits.\n",
               routine);
     }

     return(GDI_SUCCESS);
}

static
dbStatus
pg_create_get_comment(dbconn)
dbConn *dbconn;
{
     char       Query[275];
     dbObj      *result_obj=NULL;
     dbStatus   status;

     (void) strcpy(Query,
     "define function s2k_get_comment (language=\"postquel\", returntype=text) \
         arg is (char16, char16) as \"retrieve (s2k_comments.s2k_comment) \
         where s2k_comments.s2k_name = $1 and s2k_comments.s2k_is_a = $2\" ");

#ifndef DEC
     assert( strlen(Query) < sizeof(Query) );
#endif

     status = gdi_submit(dbconn, Query, GDI_FETCH_ALL, constr, &result_obj);
     result_obj = gdi_obj_destroy (result_obj);
     if(status == GDI_FAILURE)
         return(GDI_FAILURE);

     (void) strcpy(Query,
          "append s2k_comments (s2k_name=\"s2k_get_comment\", s2k_is_a=\"function\", \
          s2k_comment=\"pass it s2k_name and s2k_is_a \")");

#ifndef DEC
     assert( strlen(Query) < sizeof(Query) );
#endif

     status=gdi_submit(dbconn, Query, GDI_FETCH_ALL, constr, &result_obj);
     result_obj = gdi_obj_destroy (result_obj);
     return(status);
     
}


static
dbStatus
pg_create_inherits(dbconn)
dbConn *dbconn;
{
     char       Query[500];
     dbObj      *result_obj=NULL;
     dbStatus   status;

     (void) strcpy(Query,
     "define function s2k_inherits (language=\"postquel\", returntype=int4) \
     arg is (oid, char16) as \"retrieve (total = count {a1.oid \
     from a1 in pg_attribute, a2 in pg_attribute \
     where a1.attrelid = $1 and a1.attname = $2 and a1.attname = a2.attname \
     and (a2.attrelid = pg_inherits.inhparent \
     and a1.attrelid = pg_inherits.inhrel) })\"");

#ifndef DEC
     assert( strlen(Query) < sizeof(Query) );
#endif

     status = gdi_submit(dbconn, Query, GDI_FETCH_ALL, constr, &result_obj);
     result_obj = gdi_obj_destroy (result_obj);
     if(status == GDI_FAILURE)
         return(GDI_FAILURE);

     (void) strcpy(Query,
          "append s2k_comments (s2k_name=\"s2k_inherits\", s2k_is_a=\"function\", \
          s2k_comment=\"says if attname is inherited\")");

#ifndef DEC
     assert( strlen(Query) < sizeof(Query) );
#endif

     status=gdi_submit(dbconn, Query, GDI_FETCH_ALL, constr, &result_obj);
     result_obj = gdi_obj_destroy (result_obj);
     return(status);
     
}
static
dbStatus
pg_create_comment(dbconn)
dbConn *dbconn;
{
     char     Query[200];
     dbObj    *result_obj=NULL;
     dbStatus status;

     bzero(Query, sizeof(Query));

     /* =========== create s2k_comments class =============== */
     (void) strcpy(Query,
          "create s2k_comments(s2k_name=char16, s2k_is_a=char16, s2k_comment=text, s2k_description=text)");

#ifndef DEC
     assert( strlen(Query) < sizeof(Query) );
#endif

     status=gdi_submit(dbconn, Query, GDI_FETCH_ALL, constr, &result_obj);
     result_obj = gdi_obj_destroy (result_obj);
     if(status == GDI_FAILURE)
         return(GDI_FAILURE);


     /* ============   Comment s2k_comments ============   */

     (void) strcpy(Query,
          "append s2k_comments (s2k_name=\"s2k_comments\", s2k_is_a=\"class\", \
          s2k_comment=\"stores S2K object descriptions\")");

#ifndef DEC
     assert( strlen(Query) < sizeof(Query) );
#endif

     status=gdi_submit(dbconn, Query, GDI_FETCH_ALL, constr, &result_obj);
     result_obj = gdi_obj_destroy (result_obj);
     if(status == GDI_FAILURE)
         return(GDI_FAILURE);

     (void) strcpy(Query,
          "append s2k_comments (s2k_name=\"s2k_name\", s2k_is_a=\"attribute\", \
          s2k_comment=\"Object being described\")");

#ifndef DEC
     assert( strlen(Query) < sizeof(Query) );
#endif

     status=gdi_submit(dbconn, Query, GDI_FETCH_ALL, constr, &result_obj);
     result_obj = gdi_obj_destroy (result_obj);
     if(status == GDI_FAILURE)
         return(GDI_FAILURE);

     (void) strcpy(Query,
          "append s2k_comments (s2k_name=\"s2k_is_a\", s2k_is_a=\"attribute\", \
          s2k_comment=\"class? attribute? function?\")");

#ifndef DEC
     assert( strlen(Query) < sizeof(Query) );
#endif

     status=gdi_submit(dbconn, Query, GDI_FETCH_ALL, constr, &result_obj);
     result_obj = gdi_obj_destroy (result_obj);
     if(status == GDI_FAILURE)
         return(GDI_FAILURE);

     (void) sprintf(Query,
          "append s2k_comments (s2k_name=\"s2k_comment\", s2k_is_a=\"attribute\", \
          s2k_comment=\"short comment (%d characters)\")", COMMENT_SIZE);

#ifndef DEC
     assert( strlen(Query) < sizeof(Query) );
#endif

     status=gdi_submit(dbconn, Query, GDI_FETCH_ALL, constr, &result_obj);
     result_obj = gdi_obj_destroy (result_obj);
     if(status == GDI_FAILURE)
         return(GDI_FAILURE);

     (void) strcpy(Query,
          "append s2k_comments (s2k_name=\"s2k_description\", s2k_is_a=\"attribute\", \
          s2k_comment=\"long description\")");

#ifndef DEC
     assert( strlen(Query) < sizeof(Query) );
#endif

     status=gdi_submit(dbconn, Query, GDI_FETCH_ALL, constr, &result_obj);
     result_obj = gdi_obj_destroy (result_obj);
     if(status == GDI_FAILURE)
         return(GDI_FAILURE);

     /* create index */

     (void) strcpy(Query,
    "define index s2k_namex on s2k_comments using btree (s2k_name char16_ops)");

#ifndef DEC
     assert( strlen(Query) < sizeof(Query) );
#endif

     status=gdi_submit(dbconn, Query, GDI_FETCH_ALL, constr, &result_obj);
     result_obj = gdi_obj_destroy (result_obj);
     if(status == GDI_FAILURE)
         return(GDI_FAILURE);

     (void) sprintf(Query,
          "append s2k_comments (s2k_name=\"s2k_namex\", s2k_is_a=\"index\", \
          s2k_comment=\"index on s2k_comments class\")");

#ifndef DEC
     assert( strlen(Query) < sizeof(Query) );
#endif

     status=gdi_submit(dbconn, Query, GDI_FETCH_ALL, constr, &result_obj);
     result_obj = gdi_obj_destroy (result_obj);
     if(status == GDI_FAILURE)
         return(GDI_FAILURE);
     return(status);
}
