提交 629e8951 编写于 作者: V Vadim B. Mikheev

Trigger function for inserting user names.

Install compiled functions into $(LIBDIR)/contrib.
(Thanks to Brook Milligan <brook@trillium.NMSU.Edu>)
上级 962c8bd6
......@@ -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:
......
......@@ -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).
/*
* 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);
}
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;
DROP FUNCTION insert_username();
CREATE FUNCTION insert_username()
RETURNS opaque
AS '_OBJWD_/insert_username_DLSUFFIX_'
LANGUAGE 'c';
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册