Trigger function for inserting user names.

Install compiled functions into $(LIBDIR)/contrib.
(Thanks to Brook Milligan <brook@trillium.NMSU.Edu>)
This commit is contained in:
Vadim B. Mikheev 1997-10-17 09:55:34 +00:00
parent 962c8bd66d
commit 629e895101
5 changed files with 129 additions and 2 deletions

View File

@ -3,6 +3,8 @@ SRCDIR= ../../src
include $(SRCDIR)/Makefile.global
CONTRIBDIR=$(LIBDIR)/contrib
CFLAGS+= $(CFLAGS_SL) -I$(SRCDIR)/include
ifdef REFINT_VERBOSE
@ -10,16 +12,24 @@ CFLAGS+= -DREFINT_VERBOSE
endif
TARGETS= refint$(DLSUFFIX) refint.sql timetravel$(DLSUFFIX) timetravel.sql \
autoinc$(DLSUFFIX) autoinc.sql
autoinc$(DLSUFFIX) autoinc.sql \
insert_username$(DLSUFFIX) insert_username.sql
CLEANFILES+= $(TARGETS)
all:: $(TARGETS)
install:: all $(CONTRIBDIR)
$(INSTALL) -c README $(CONTRIBDIR)/README.spi
for f in *.example *.sql *$(DLSUFFIX); do $(INSTALL) -c $$f $(CONTRIBDIR)/$$f; done
$(CONTRIBDIR):
mkdir -p $(CONTRIBDIR)
%.sql: %.source
rm -f $@; \
C=`pwd`; \
sed -e "s:_OBJWD_:$$C:g" \
sed -e "s:_OBJWD_:$(CONTRIBDIR):g" \
-e "s:_DLSUFFIX_:$(DLSUFFIX):g" < $< > $@
clean:

View File

@ -122,3 +122,16 @@ as many column/sequence pairs as you need).
autoinc.source).
4. insert_username.c - function for inserting user names.
You have to create BEFORE INSERT OR UPDATE trigger using the function
insert_username(). You have to specify as a function argument: the column
name (of text type) in which user names will be inserted. Note that user
names will be inserted irregardless of the initial value of the field, so
that users cannot bypass this functionality by simply defining the field to
be NOT NULL.
There is an example in insert_username.example.
To CREATE FUNCTION use insert_username.sql (will be made by gmake from
insert_username.source).

View File

@ -0,0 +1,77 @@
/*
* insert_username.c
* $Modified: Thu Oct 16 08:13:42 1997 by brook $
*
* insert user name in response to a trigger
* usage: insert_username (column_name)
*/
#include "executor/spi.h" /* this is what you need to work with SPI */
#include "commands/trigger.h" /* -"- and triggers */
#include "miscadmin.h" /* for GetPgUserName() */
HeapTuple insert_username (void);
HeapTuple
insert_username ()
{
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;
/* sanity checks from autoinc.c */
if (!CurrentTriggerData)
elog(WARN, "insert_username: triggers are not initialized");
if (TRIGGER_FIRED_FOR_STATEMENT(CurrentTriggerData->tg_event))
elog(WARN, "insert_username: can't process STATEMENT events");
if (TRIGGER_FIRED_AFTER(CurrentTriggerData->tg_event))
elog(WARN, "insert_username: 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(WARN, "insert_username: can't process DELETE events");
rel = CurrentTriggerData->tg_relation;
relname = SPI_getrelname(rel);
trigger = CurrentTriggerData->tg_trigger;
nargs = trigger->tgnargs;
if (nargs != 1)
elog(WARN, "insert_username (%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(WARN, "insert_username (%s): there is no attribute %s", relname, args[0]);
if (SPI_gettypeid (tupdesc, attnum) != TEXTOID)
elog(WARN, "insert_username (%s): attribute %s must be of TEXT type",
relname, args[0]);
/* create fields containing name */
newval = PointerGetDatum (textin (GetPgUserName ()));
/* construct new tuple */
rettuple = SPI_modifytuple (rel, rettuple, 1, &attnum, &newval, NULL);
if ( rettuple == NULL )
elog (WARN, "insert_username (%s): %d returned by SPI_modifytuple",
relname, SPI_result);
pfree (relname);
return (rettuple);
}

View File

@ -0,0 +1,21 @@
DROP TABLE username_test;
CREATE TABLE username_test (
name text,
username text not null
);
CREATE TRIGGER insert_usernames
BEFORE INSERT OR UPDATE ON username_test
FOR EACH ROW
EXECUTE PROCEDURE insert_username (username);
INSERT INTO username_test VALUES ('nothing');
INSERT INTO username_test VALUES ('null', null);
INSERT INTO username_test VALUES ('empty string', '');
INSERT INTO username_test VALUES ('space', ' ');
INSERT INTO username_test VALUES ('tab', ' ');
INSERT INTO username_test VALUES ('name', 'name');
SELECT * FROM username_test;

View File

@ -0,0 +1,6 @@
DROP FUNCTION insert_username();
CREATE FUNCTION insert_username()
RETURNS opaque
AS '_OBJWD_/insert_username_DLSUFFIX_'
LANGUAGE 'c';