include $(SRCDIR)/Makefile.global
+CONTRIBDIR=$(LIBDIR)/contrib
+
CFLAGS+= $(CFLAGS_SL) -I$(SRCDIR)/include
ifdef REFINT_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:
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).
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+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;
+