'C' function (spi?) for datetime UPDATE trigger - HOW? - Mailing list pgsql-admin

From Terry Mackintosh
Subject 'C' function (spi?) for datetime UPDATE trigger - HOW?
Date
Msg-id Pine.LNX.3.95.980819110507.27599B-100000@terry1.acun.com
Whole thread Raw
List pgsql-admin
Hi All

I hope this is the right list:)

I sent this in a few days ago, but got no reply, so now I have joined the
list and send it again hoping to get a reply, or atleast get directed to
the right list if this is not it.

Need: Update a datetime field to the current time upon a record being
UPDATE'd. (To keep track of modification times)

This seems pertty basic, has any one already done this?
I am very open to any better approaches/ideas.

How I tryed to do it: (see comments below)
Starting with /usr/src/pgsql/contrib/spi/insert_username.c
I turned it into dtstamp.c as follows:

/*
 * dtstamp.c (DateTimeSTAMP.c) was insert_username.c
 * $Modified: Thu Oct 16 08:13:42 1997 by brook $
 * $Modified: Sun Aug 16 1998 by Terry Mackintosh $
 *
 * update a datetime colum in response to a trigger
 * usage:  dtstamp(column_name)
 */

#include "executor/spi.h"    /* this is what you need to work with SPI */
#include "commands/trigger.h"    /* -"- and triggers */
#include <time.h>
/* #include "miscadmin.h"    /* Prob. not needed? for GetPgUserName() */

HeapTuple    dtstamp(void);

HeapTuple dtstamp(void)
{
    Trigger     *trigger;        /* to get trigger name */
    int        nargs;            /* # of arguments */
/*    Datum        newval;            /* new value of column */
    char        **args;            /* arguments */
    char        *relname;        /* triggered relation name */
    Relation    rel;            /* triggered relation */
    HeapTuple    rettuple = NULL;
    TupleDesc    tupdesc;        /* tuple description */
    int        attnum;

/* New, create a datetime string as m/d/y h:m */

    time_t        runningtime;        /* time in seconds */
    struct    tm    *tptr;            /* a time structure */
    char        datetime[20];        /* will have the finished p. */

    time( &runningtime );
    tptr = localtime(&runningtime);
    sprintf( datetime, "%d/%d/%d %d:%d", tptr->tm_mon, tptr->tm_mday, tptr->tm_year + 1900, tptr->tm_hour, tptr->tm_min
);

/* End New for now, more at the bottom */

    /* sanity checks from dtstamp.c */
    if (!CurrentTriggerData)
        elog(ERROR, "dtstamp: triggers are not initialized");

    if (TRIGGER_FIRED_FOR_STATEMENT(CurrentTriggerData->tg_event))
        elog(ERROR, "dtstamp: can't process STATEMENT events");

    if (TRIGGER_FIRED_AFTER(CurrentTriggerData->tg_event))
        elog(ERROR, "dtstamp: must be fired before event");

    if (TRIGGER_FIRED_BY_INSERT(CurrentTriggerData->tg_event))
        rettuple = CurrentTriggerData->tg_trigtuple;
    else if (TRIGGER_FIRED_BY_UPDATE(CurrentTriggerData->tg_event))
        rettuple = CurrentTriggerData->tg_newtuple;
    else
        elog(ERROR, "dtstamp: can't process DELETE events");

    rel = CurrentTriggerData->tg_relation;
    relname = SPI_getrelname(rel);

    trigger = CurrentTriggerData->tg_trigger;

    nargs = trigger->tgnargs;
    if (nargs != 1)
        elog(ERROR, "dtstamp (%s): one argument was expected", relname);

    args = trigger->tgargs;
    tupdesc = rel->rd_att;

    CurrentTriggerData = NULL;

    attnum = SPI_fnumber(tupdesc, args[0]);

    if (attnum < 0)
        elog(ERROR, "dtstamp (%s): there is no attribute %s", relname, args[0]);

/* More NEW stuff

    if (SPI_gettypeid(tupdesc, attnum) != DATETIMEOID)
The problem here is, what should this    -----^^^^^^^^^^^ be for a
datetime field?

        elog(ERROR, "dtstamp (%s): attribute %s must be of DATETIME type.", relname, args[0] );
*/
    /* construct new tuple */
/* The next problem is, what is the 'Datum' type?? can it some how be passed
   a datetime??
*/
    rettuple = SPI_modifytuple(rel, rettuple, 1, &attnum, (Datum *) &datetime, NULL);
    if (rettuple == NULL)
        elog(ERROR, "dtstamp (%s): %d returned by SPI_modifytuple", relname, SPI_result);

    pfree(relname);

    return (rettuple);
}

Any (better:) ideas?

Thanks, and have a great day
Terry Mackintosh <terry@terrym.com>          http://www.terrym.com
sysadmin/owner  Please! No MIME encoded or HTML mail, unless needed.

Proudly powered by R H Linux 4.2, Apache 1.3, PHP 3, PostgreSQL 6.3
-------------------------------------------------------------------
Success Is A Choice ... book by Rick Patino, get it, read it!



pgsql-admin by date:

Previous
From: Bruce Momjian
Date:
Subject: Re: [ADMIN] Re: user is not in "pg_shadow"
Next
From: Mateus Cordeiro Inssa
Date:
Subject: [ADMIN] 'C' function (spi?) for datetime UPDATE trigger - HOW?