summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Kreen2008-03-07 16:47:46 +0000
committerMarko Kreen2008-03-07 16:47:46 +0000
commit647d950e95e30519bc6cfc68b004d385fd8482ff (patch)
treef958003b72f5999d90d3b9affef5a70afc8afafa
parentd24678ff68a228ae785908aa4eeffb3b779e27c1 (diff)
pgq/triggers: allow making backup of old row in ev_extra2
also clean up some common code
-rw-r--r--sql/pgq/triggers/common.c55
-rw-r--r--sql/pgq/triggers/common.h9
-rw-r--r--sql/pgq/triggers/logtriga.c7
-rw-r--r--sql/pgq/triggers/logutriga.c12
-rw-r--r--sql/pgq/triggers/pgq_triggers.sql.in4
-rw-r--r--sql/pgq/triggers/sqltriga.c8
6 files changed, 60 insertions, 35 deletions
diff --git a/sql/pgq/triggers/common.c b/sql/pgq/triggers/common.c
index 26668b30..00de90c5 100644
--- a/sql/pgq/triggers/common.c
+++ b/sql/pgq/triggers/common.c
@@ -57,18 +57,19 @@ static void relcache_reset_cb(Datum arg, Oid relid);
*
* does not support NULL arguments.
*/
-void pgq_simple_insert(const char *queue_name, Datum ev_type, Datum ev_data, Datum ev_extra1)
+void pgq_simple_insert(const char *queue_name, Datum ev_type, Datum ev_data, Datum ev_extra1, Datum ev_extra2)
{
- Datum values[4];
+ Datum values[5];
+ char nulls[5];
static void *plan = NULL;
int res;
if (!plan) {
const char *sql;
- Oid types[4] = { TEXTOID, TEXTOID, TEXTOID, TEXTOID };
+ Oid types[5] = { TEXTOID, TEXTOID, TEXTOID, TEXTOID, TEXTOID };
- sql = "select pgq.insert_event($1, $2, $3, $4, null, null, null)";
- plan = SPI_saveplan(SPI_prepare(sql, 4, types));
+ sql = "select pgq.insert_event($1, $2, $3, $4, $5, null, null)";
+ plan = SPI_saveplan(SPI_prepare(sql, 5, types));
if (plan == NULL)
elog(ERROR, "logtriga: SPI_prepare() failed");
}
@@ -76,11 +77,28 @@ void pgq_simple_insert(const char *queue_name, Datum ev_type, Datum ev_data, Dat
values[1] = ev_type;
values[2] = ev_data;
values[3] = ev_extra1;
- res = SPI_execute_plan(plan, values, NULL, false, 0);
+ values[4] = ev_extra2;
+ nulls[0] = ' ';
+ nulls[1] = ' ';
+ nulls[2] = ' ';
+ nulls[3] = ' ';
+ nulls[4] = ev_extra2 ? ' ' : 'n';
+ res = SPI_execute_plan(plan, values, nulls, false, 0);
if (res != SPI_OK_SELECT)
elog(ERROR, "call of pgq.insert_event failed");
}
+void pgq_insert_tg_event(PgqTriggerEvent *ev)
+{
+ pgq_simple_insert(ev->queue_name,
+ pgq_finish_varbuf(ev->ev_type),
+ pgq_finish_varbuf(ev->ev_data),
+ pgq_finish_varbuf(ev->ev_extra1),
+ ev->ev_extra2
+ ? pgq_finish_varbuf(ev->ev_extra2)
+ : (Datum)0);
+}
+
char *pgq_find_table_name(Relation rel)
{
NameData tname = rel->rd_rel->relname;
@@ -272,6 +290,8 @@ parse_newstyle_args(PgqTriggerEvent *ev, TriggerData *tg)
ev->ignore_list = arg + 7;
else if (strncmp(arg, "pkey=", 5) == 0)
ev->pkey_list = arg + 5;
+ else if (strcmp(arg, "backup") == 0)
+ ev->backup = true;
else
elog(ERROR, "bad param to pgq trigger");
}
@@ -344,14 +364,6 @@ void pgq_prepare_event(struct PgqTriggerEvent *ev, TriggerData *tg, bool newstyl
elog(ERROR, "unknown event for pgq trigger");
/*
- * init data
- */
- ev->ev_type = pgq_init_varbuf();
- ev->ev_data = pgq_init_varbuf();
- ev->ev_extra1 = pgq_init_varbuf();
- ev->ev_extra2 = pgq_init_varbuf();
-
- /*
* load table info
*/
ev->info = pgq_find_table_info(tg->tg_relation);
@@ -365,6 +377,21 @@ void pgq_prepare_event(struct PgqTriggerEvent *ev, TriggerData *tg, bool newstyl
parse_newstyle_args(ev, tg);
else
parse_oldstyle_args(ev, tg);
+
+ /*
+ * init data
+ */
+ ev->ev_type = pgq_init_varbuf();
+ ev->ev_data = pgq_init_varbuf();
+ ev->ev_extra1 = pgq_init_varbuf();
+
+ /*
+ * Do the backup, if requested.
+ */
+ if (ev->backup) {
+ ev->ev_extra2 = pgq_init_varbuf();
+ pgq_urlenc_row(ev, tg, tg->tg_trigtuple, ev->ev_extra2);
+ }
}
/*
diff --git a/sql/pgq/triggers/common.h b/sql/pgq/triggers/common.h
index 3cbbdc06..55319692 100644
--- a/sql/pgq/triggers/common.h
+++ b/sql/pgq/triggers/common.h
@@ -13,6 +13,7 @@ struct PgqTriggerEvent {
char op_type;
bool skip;
+ bool backup;
struct PgqTableInfo *info;
@@ -41,10 +42,14 @@ struct PgqTableInfo {
struct PgqTableInfo *pgq_find_table_info(Relation rel);
void pgq_prepare_event(struct PgqTriggerEvent *ev, TriggerData *tg, bool newstyle);
char *pgq_find_table_name(Relation rel);
-void pgq_simple_insert(const char *queue_name, Datum ev_type, Datum ev_data, Datum ev_extra1);
+void pgq_simple_insert(const char *queue_name, Datum ev_type, Datum ev_data, Datum ev_extra1, Datum ev_extra2);
bool pgqtriga_skip_col(PgqTriggerEvent *ev, TriggerData *tg, int i, int attkind_idx);
bool pgqtriga_is_pkey(PgqTriggerEvent *ev, TriggerData *tg, int i, int attkind_idx);
+void pgq_insert_tg_event(PgqTriggerEvent *ev);
-/* makesql */
+/* makesql.c */
int pgqtriga_make_sql(PgqTriggerEvent *ev, TriggerData *tg, StringInfo sql);
+/* logutriga.c */
+void pgq_urlenc_row(PgqTriggerEvent *ev, TriggerData *tg, HeapTuple row, StringInfo buf);
+
diff --git a/sql/pgq/triggers/logtriga.c b/sql/pgq/triggers/logtriga.c
index 5ba8c1b8..d27cfb54 100644
--- a/sql/pgq/triggers/logtriga.c
+++ b/sql/pgq/triggers/logtriga.c
@@ -71,12 +71,7 @@ pgq_logtriga(PG_FUNCTION_ARGS)
* create sql and insert if interesting
*/
if (pgqtriga_make_sql(&ev, tg, ev.ev_data))
- {
- pgq_simple_insert(ev.queue_name,
- pgq_finish_varbuf(ev.ev_type),
- pgq_finish_varbuf(ev.ev_data),
- pgq_finish_varbuf(ev.ev_extra1));
- }
+ pgq_insert_tg_event(&ev);
if (SPI_finish() < 0)
elog(ERROR, "SPI_finish failed");
diff --git a/sql/pgq/triggers/logutriga.c b/sql/pgq/triggers/logutriga.c
index ecaf5b8e..17819c58 100644
--- a/sql/pgq/triggers/logutriga.c
+++ b/sql/pgq/triggers/logutriga.c
@@ -27,8 +27,8 @@
PG_FUNCTION_INFO_V1(pgq_logutriga);
Datum pgq_logutriga(PG_FUNCTION_ARGS);
-static void
-process_row_data(PgqTriggerEvent *ev, TriggerData *tg, HeapTuple row, StringInfo buf)
+void
+pgq_urlenc_row(PgqTriggerEvent *ev, TriggerData *tg, HeapTuple row, StringInfo buf)
{
TupleDesc tupdesc = tg->tg_relation->rd_att;
bool first = true;
@@ -74,6 +74,7 @@ process_row_data(PgqTriggerEvent *ev, TriggerData *tg, HeapTuple row, StringInfo
* ev_type - operation type, I/U/D
* ev_data - urlencoded column values
* ev_extra1 - table name
+ * ev_extra2 - optional urlencoded backup
*/
Datum
pgq_logutriga(PG_FUNCTION_ARGS)
@@ -111,15 +112,12 @@ pgq_logutriga(PG_FUNCTION_ARGS)
/*
* create type, data
*/
- process_row_data(&ev, tg, row, ev.ev_data);
+ pgq_urlenc_row(&ev, tg, row, ev.ev_data);
/*
* Construct the parameter array and insert the log row.
*/
- pgq_simple_insert(ev.queue_name,
- pgq_finish_varbuf(ev.ev_type),
- pgq_finish_varbuf(ev.ev_data),
- pgq_finish_varbuf(ev.ev_extra1));
+ pgq_insert_tg_event(&ev);
if (SPI_finish() < 0)
elog(ERROR, "SPI_finish failed");
diff --git a/sql/pgq/triggers/pgq_triggers.sql.in b/sql/pgq/triggers/pgq_triggers.sql.in
index d3e0d978..93f9ba7a 100644
--- a/sql/pgq/triggers/pgq_triggers.sql.in
+++ b/sql/pgq/triggers/pgq_triggers.sql.in
@@ -48,11 +48,13 @@ AS 'MODULE_PATHNAME', 'pgq_logtriga' LANGUAGE C;
-- SKIP - The actual operation should be skipped
-- ignore=col1[,col2] - don't look at the specified arguments
-- pkey=col1[,col2] - Set pkey fields for the table, autodetection will be skipped
+-- backup - Put urlencoded contents of old row to ev_extra2
--
-- Queue event fields:
-- ev_type - I/U/D
-- ev_data - partial SQL statement
-- ev_extra1 - table name
+-- ev_extra2 - optional urlencoded backup
--
-- ----------------------------------------------------------------------
CREATE OR REPLACE FUNCTION pgq.sqltriga() RETURNS trigger
@@ -76,11 +78,13 @@ AS 'MODULE_PATHNAME', 'pgq_sqltriga' LANGUAGE C;
-- SKIP - The actual operation should be skipped
-- ignore=col1[,col2] - don't look at the specified arguments
-- pkey=col1[,col2] - Set pkey fields for the table, autodetection will be skipped
+-- backup - Put urlencoded contents of old row to ev_extra2
--
-- Queue event fields:
-- ev_type - I/U/D ':' pkey_column_list
-- ev_data - column values urlencoded
-- ev_extra1 - table name
+-- ev_extra2 - optional urlencoded backup
--
-- Regular listen trigger example:
-- > CREATE TRIGGER triga_nimi AFTER INSERT OR UPDATE ON customer
diff --git a/sql/pgq/triggers/sqltriga.c b/sql/pgq/triggers/sqltriga.c
index b20a299a..094cc319 100644
--- a/sql/pgq/triggers/sqltriga.c
+++ b/sql/pgq/triggers/sqltriga.c
@@ -35,6 +35,7 @@ Datum pgq_sqltriga(PG_FUNCTION_ARGS);
* ev_type - operation type, I/U/D
* ev_data - urlencoded column values
* ev_extra1 - table name
+ * ev_extra2 - optional urlencoded backup
*/
Datum
pgq_sqltriga(PG_FUNCTION_ARGS)
@@ -64,12 +65,7 @@ pgq_sqltriga(PG_FUNCTION_ARGS)
* create sql and insert if interesting
*/
if (pgqtriga_make_sql(&ev, tg, ev.ev_data))
- {
- pgq_simple_insert(ev.queue_name,
- pgq_finish_varbuf(ev.ev_type),
- pgq_finish_varbuf(ev.ev_data),
- pgq_finish_varbuf(ev.ev_extra1));
- }
+ pgq_insert_tg_event(&ev);
if (SPI_finish() < 0)
elog(ERROR, "SPI_finish failed");