Welcome to the CHICKEN Scheme pasting service
postgres trigger added by mercora on Mon Jun 27 23:35:13 2011
#include <sys/socket.h> #include <arpa/inet.h> #include <netinet/in.h> #include "postgresql/server/postgres.h" #include "postgresql/server/fmgr.h" #include "postgresql/server/commands/trigger.h" #include "postgresql/server/executor/spi.h" #include "postgresql/server/catalog/pg_type.h" #ifdef PG_MODULE_MAGIC PG_MODULE_MAGIC; #endif #define SERVER_HOST "127.0.0.1" #define SERVER_PORT 7676 extern Datum miner_triggerf(PG_FUNCTION_ARGS); // TODO: make this function accept a host an port to make it to something like dump_row_as_json_to_socket() Datum miner_triggerf(PG_FUNCTION_ARGS){ TriggerData *trigger_data = (TriggerData *) fcinfo->context; TupleDesc tuple_desc; HeapTuple returned_tuple; //leave row untouched if (TRIGGER_FIRED_BY_UPDATE(trigger_data->tg_event)) returned_tuple = trigger_data->tg_newtuple; else returned_tuple = trigger_data->tg_trigtuple; //build json from row char json_row[8192]; //big enough ? what could went wrong ? ;P char *json_buffer; memset(&json_row, 0, sizeof(json_row)); json_buffer = SPI_getrelname(trigger_data->tg_relation); sprintf(json_row, "{ \"table\": \"%s\", \"data\": { ", json_buffer); pfree(json_buffer); int i; for(i = 1; (json_buffer = SPI_fname(trigger_data->tg_relation->rd_att, i)) != NULL; i++){ if(i != 1) strcat(json_row, ", "); sprintf(json_row, "%s \"%s\": ", json_row, json_buffer); pfree(json_buffer); // json/js may comes with restrictions on how thoses are displayed // says "All numbers in Javascript are 64 bit "double" precision IEE754 floating point." // Numeric in postgres is an arbitrary precision number .... does arbitrary fit in IEE754 floating point ?!? ;P switch(SPI_gettypeid(trigger_data->tg_relation->rd_att, i)){ case INT4OID: case INT8OID: case NUMERICOID: json_buffer = SPI_getvalue(returned_tuple, trigger_data->tg_relation->rd_att, i); sprintf(json_row, "%s%s", json_row, json_buffer); break; case TIMESTAMPTZOID: //format returned by SPI_getvalue() is parseable by Datum() in js default: json_buffer = SPI_getvalue(returned_tuple, trigger_data->tg_relation->rd_att, i); sprintf(json_row, "%s\"%s\"", json_row, json_buffer); } pfree(json_buffer); } strcat(json_row, " } }"); elog (WARNING, json_row); //send json to socket int notify_socket; struct sockaddr_in notify_socket_address; memset(¬ify_socket_address, 0, sizeof(notify_socket_address)); notify_socket_address.sin_family = AF_INET; notify_socket_address.sin_port = htons(SERVER_PORT); notify_socket_address.sin_addr.s_addr = inet_addr(SERVER_HOST); if((notify_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1){ elog (WARNING, "failed to create miner notififaction socket"); }else{ if((sendto(notify_socket, json_row, strlen(json_row), 0, (struct sockaddr *) ¬ify_socket_address, sizeof(struct sockaddr))) == -1){ elog (WARNING, "failed to send message to miner notififaction socket"); } } close(notify_socket); return (Datum) returned_tuple; }