/[rserv]/lib/rserv.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /lib/rserv.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1.1.1 by dpavlin, Wed Dec 20 17:22:35 2000 UTC revision 1.5 by dpavlin, Mon Nov 3 21:30:37 2003 UTC
# Line 3  Line 3 
3   * (c) 2000 Vadim Mikheev, PostgreSQL Inc.   * (c) 2000 Vadim Mikheev, PostgreSQL Inc.
4   */   */
5    
6  #include "executor/spi.h"               /* this is what you need to work with SPI */  #include "executor/spi.h"       /* this is what you need to work with SPI */
7  #include "commands/trigger.h"   /* -"- and triggers */  #include "commands/trigger.h"   /* -"- and triggers */
8  #include "utils/tqual.h"                /* -"- and SnapshotData */  #include "utils/tqual.h"        /* -"- and SnapshotData */
9  #include <ctype.h>                              /* tolower () */  #include <ctype.h>              /* tolower () */
10    
11  #ifdef PG_FUNCTION_INFO_V1  #ifdef PG_FUNCTION_INFO_V1
12  #define CurrentTriggerData ((TriggerData *) fcinfo->context)  #define CurrentTriggerData ((TriggerData *) fcinfo->context)
# Line 16  Line 16 
16  PG_FUNCTION_INFO_V1(_rserv_log_);  PG_FUNCTION_INFO_V1(_rserv_log_);
17  PG_FUNCTION_INFO_V1(_rserv_sync_);  PG_FUNCTION_INFO_V1(_rserv_sync_);
18  PG_FUNCTION_INFO_V1(_rserv_debug_);  PG_FUNCTION_INFO_V1(_rserv_debug_);
19  Datum _rserv_log_(PG_FUNCTION_ARGS);  PG_FUNCTION_INFO_V1(_rserv_xid_);
20  Datum _rserv_sync_(PG_FUNCTION_ARGS);  Datum           _rserv_log_(PG_FUNCTION_ARGS);
21  Datum _rserv_debug_(PG_FUNCTION_ARGS);  Datum           _rserv_sync_(PG_FUNCTION_ARGS);
22    Datum           _rserv_debug_(PG_FUNCTION_ARGS);
23    Datum           _rserv_xid_(PG_FUNCTION_ARGS);
24    
25  #else  #else
26  HeapTuple       _rserv_log_(void);  HeapTuple       _rserv_log_(void);
27  int32           _rserv_sync_(int32);  int32           _rserv_sync_(int32);
28  int32           _rserv_debug_(int32);  int32           _rserv_debug_(int32);
29    int32           _rserv_xid_(void);
30  #endif  #endif
31    
32  static int      debug = 0;  static int      debug = 0;
33    
34  static char* OutputValue(char *key, char *buf, int size);  static char *OutputValue(char *key, char *buf, int size);
35    
36  #ifdef PG_FUNCTION_INFO_V1  #ifdef PG_FUNCTION_INFO_V1
37  Datum  Datum
# Line 42  _rserv_log_() Line 46  _rserv_log_()
46          char      **args;                       /* argument: argnum */          char      **args;                       /* argument: argnum */
47          Relation        rel;                    /* triggered relation */          Relation        rel;                    /* triggered relation */
48          HeapTuple       tuple;                  /* tuple to return */          HeapTuple       tuple;                  /* tuple to return */
49          HeapTuple       newtuple = NULL;/* tuple to return */          HeapTuple       newtuple = NULL;        /* tuple to return */
50          TupleDesc       tupdesc;                /* tuple description */          TupleDesc       tupdesc;                /* tuple description */
51          int                     keynum;          int                     keynum;
52          char       *key;          char       *key;
53          char       *okey;          char       *okey;
54          char       *newkey = NULL;          char       *newkey = NULL;
55          int                     deleted;          int                     deleted, inserted, updated;
56          char            sql[8192];          char            sql[8192];
57          char            outbuf[8192];          char            outbuf[8192];
58          char            oidbuf[64];          char            oidbuf[64];
59          int                     ret;          int                     ret;
60            int             server;
61    
62          /* Called by trigger manager ? */          /* Called by trigger manager ? */
63          if (!CurrentTriggerData)          if (!CurrentTriggerData)
# Line 68  _rserv_log_() Line 73  _rserv_log_()
73          nargs = trigger->tgnargs;          nargs = trigger->tgnargs;
74          args = trigger->tgargs;          args = trigger->tgargs;
75    
76          if (nargs != 1)                 /* odd number of arguments! */          if (nargs != 2)                         /* odd number of arguments! */
77                  elog(ERROR, "_rserv_log_: need in *one* argument");                  elog(ERROR, "_rserv_log_: need in *two* arguments, key number and server number");
78    
79          keynum = atoi(args[0]);          keynum = atoi(args[0]);
80            server = atoi(args[1]);
81    
82          if (keynum < 0 && keynum != ObjectIdAttributeNumber)          if (keynum < 0 && keynum != ObjectIdAttributeNumber)
83                  elog(ERROR, "_rserv_log_: invalid keynum %d", keynum);                  elog(ERROR, "_rserv_log_: invalid keynum %d", keynum);
# Line 79  _rserv_log_() Line 85  _rserv_log_()
85          rel = CurrentTriggerData->tg_relation;          rel = CurrentTriggerData->tg_relation;
86          tupdesc = rel->rd_att;          tupdesc = rel->rd_att;
87    
88          deleted = (TRIGGER_FIRED_BY_DELETE(CurrentTriggerData->tg_event)) ?          deleted = (TRIGGER_FIRED_BY_DELETE(CurrentTriggerData->tg_event)) ?
89                  1 : 0;                  1 : 0;
90    
91          if (TRIGGER_FIRED_BY_UPDATE(CurrentTriggerData->tg_event))          inserted = (TRIGGER_FIRED_BY_INSERT(CurrentTriggerData->tg_event)) ? 1 : 0;
92    
93            updated = 0;
94            if (TRIGGER_FIRED_BY_UPDATE(CurrentTriggerData->tg_event)) {
95                    updated = 1;
96                  newtuple = CurrentTriggerData->tg_newtuple;                  newtuple = CurrentTriggerData->tg_newtuple;
97            }
98    
99    #ifndef PG_FUNCTION_INFO_V1
100    
101          /*          /*
102           * Setting CurrentTriggerData to NULL prevents direct calls to trigger           * Setting CurrentTriggerData to NULL prevents direct calls to trigger
# Line 91  _rserv_log_() Line 104  _rserv_log_()
104           * by trigger manager code only.           * by trigger manager code only.
105           */           */
106          CurrentTriggerData = NULL;          CurrentTriggerData = NULL;
107    #endif
108    
109          /* Connect to SPI manager */          /* Connect to SPI manager */
110          if ((ret = SPI_connect()) < 0)          if ((ret = SPI_connect()) < 0)
# Line 98  _rserv_log_() Line 112  _rserv_log_()
112    
113          if (keynum == ObjectIdAttributeNumber)          if (keynum == ObjectIdAttributeNumber)
114          {          {
115                  sprintf(oidbuf, "%u", tuple->t_data->t_oid);                  snprintf(oidbuf, sizeof(oidbuf), "%u", HeapTupleGetOid(tuple));
116                  key = oidbuf;                  key = oidbuf;
117          }          }
118          else          else
# Line 115  _rserv_log_() Line 129  _rserv_log_()
129                  if (strcmp(newkey, key) == 0)                  if (strcmp(newkey, key) == 0)
130                          newkey = NULL;                          newkey = NULL;
131                  else                  else
132                          deleted = 1;    /* old key was deleted */                          deleted = 1;            /* old key was deleted */
133          }          }
134    
135          if (strpbrk(key, "\\    \n'"))          if (strpbrk(key, "\\    \n'"))
# Line 123  _rserv_log_() Line 137  _rserv_log_()
137          else          else
138                  okey = key;                  okey = key;
139    
140          sprintf(sql, "update _RSERV_LOG_ set logid = %d, logtime = now(), "          snprintf(sql, 8192, "update _RSERV_LOG_ set logid = %d, logtime = now(), "
141                          "deleted = %d where reloid = %u and key = '%s'",                          "insert = %d, update = %d, delete = %d where reloid = %u and key = '%s'",
142                          GetCurrentTransactionId(), deleted, rel->rd_id, okey);                          GetCurrentTransactionId(), inserted, updated, deleted, rel->rd_id, okey);
143    
144          if (debug)          if (debug)
145                  elog(NOTICE, sql);                  elog(DEBUG3, "sql: %s", sql);
146    
147          ret = SPI_exec(sql, 0);          ret = SPI_exec(sql, 0);
148    
# Line 142  _rserv_log_() Line 156  _rserv_log_()
156                  elog(ERROR, "_rserv_log_: duplicate tuples");                  elog(ERROR, "_rserv_log_: duplicate tuples");
157          else if (SPI_processed == 0)          else if (SPI_processed == 0)
158          {          {
159                  sprintf(sql, "insert into _RSERV_LOG_ "                  snprintf(sql, 8192, "insert into _RSERV_LOG_ "
160                                  "(reloid, logid, logtime, deleted, key) "                                  "(reloid, logid, logtime, insert, update, delete, key, server) "
161                                  "values (%u, %d, now(), %d, '%s')",                                  "values (%u, %d, now(), %d, %d, %d, '%s', %d)",
162                                  rel->rd_id, GetCurrentTransactionId(),                                   rel->rd_id, GetCurrentTransactionId(),
163                                  deleted, okey);                                  inserted, updated, deleted, okey, server);
164    
165                  if (debug)                  if (debug)
166                          elog(NOTICE, sql);                          elog(DEBUG3, "sql: %s", sql);
167    
168                  ret = SPI_exec(sql, 0);                  ret = SPI_exec(sql, 0);
169    
# Line 167  _rserv_log_() Line 181  _rserv_log_()
181                  else                  else
182                          okey = newkey;                          okey = newkey;
183    
184                  sprintf(sql, "insert into _RSERV_LOG_ "                  snprintf(sql, 8192, "insert into _RSERV_LOG_ "
185                                  "(reloid, logid, logtime, deleted, key) "                                   "(reloid, logid, logtime, insert, update, deleted, key, server) "
186                                  "values (%u, %d, now(), 0, '%s')",                                   "values (%u, %d, now(), %d, %d, 0, '%s', %d)",
187                                  rel->rd_id, GetCurrentTransactionId(), okey);                                   rel->rd_id, GetCurrentTransactionId(), inserted, updated, okey, server);
188    
189                  if (debug)                  if (debug)
190                          elog(NOTICE, sql);                          elog(DEBUG3, "sql: %s", sql);
191    
192                  ret = SPI_exec(sql, 0);                  ret = SPI_exec(sql, 0);
193    
# Line 202  _rserv_sync_(int32 server) Line 216  _rserv_sync_(int32 server)
216  #endif  #endif
217  {  {
218  #ifdef PG_FUNCTION_INFO_V1  #ifdef PG_FUNCTION_INFO_V1
219          int32 server = PG_GETARG_INT32(0);          int32           server = PG_GETARG_INT32(0);
220  #endif  #endif
221          char    sql[8192];          char            sql[8192];
222          char    buf[8192];          char            buf[8192];
223          char   *active = buf;          char       *active = buf;
224          uint32  xcnt;          uint32          xcnt;
225          int             ret;          int                     ret;
226    
227          if (SerializableSnapshot == NULL)          if (SerializableSnapshot == NULL)
228                  elog(ERROR, "_rserv_sync_: SerializableSnapshot is NULL");                  elog(ERROR, "_rserv_sync_: SerializableSnapshot is NULL");
# Line 216  _rserv_sync_(int32 server) Line 230  _rserv_sync_(int32 server)
230          buf[0] = 0;          buf[0] = 0;
231          for (xcnt = 0; xcnt < SerializableSnapshot->xcnt; xcnt++)          for (xcnt = 0; xcnt < SerializableSnapshot->xcnt; xcnt++)
232          {          {
233                  sprintf(buf + strlen(buf), "%s%u", (xcnt) ? ", " : "",                  snprintf(buf + strlen(buf), 8192 - strlen(buf),
234                          SerializableSnapshot->xip[xcnt]);                                   "%s%u", (xcnt) ? ", " : "",
235                                     SerializableSnapshot->xip[xcnt]);
236          }          }
237    
238          if ((ret = SPI_connect()) < 0)          if ((ret = SPI_connect()) < 0)
239                  elog(ERROR, "_rserv_sync_: SPI_connect returned %d", ret);                  elog(ERROR, "_rserv_sync_: SPI_connect returned %d", ret);
240    
241          sprintf(sql, "insert into _RSERV_SYNC_ "          snprintf(sql, 8192, "insert into _RSERV_SYNC_ "
242                          "(server, syncid, synctime, status, minid, maxid, active) "                           "(server, syncid, synctime, status, minid, maxid, active) "
243                          "values (%u, currval('_rserv_sync_seq_'), now(), 0, %d, %d, '%s')",            "values (%u, currval('_rserv_sync_seq_'), now(), 0, %d, %d, '%s')",
244                          server, SerializableSnapshot->xmin, SerializableSnapshot->xmax, active);                           server, SerializableSnapshot->xmin, SerializableSnapshot->xmax, active);
245    
246          ret = SPI_exec(sql, 0);          ret = SPI_exec(sql, 0);
247    
# Line 247  _rserv_debug_(int32 newval) Line 262  _rserv_debug_(int32 newval)
262  #endif  #endif
263  {  {
264  #ifdef PG_FUNCTION_INFO_V1  #ifdef PG_FUNCTION_INFO_V1
265          int32   newval = PG_GETARG_INT32(0);          int32           newval = PG_GETARG_INT32(0);
266  #endif  #endif
267          int32   oldval = debug;          int32           oldval = debug;
268    
269          debug = newval;          debug = newval;
270    
271          return (oldval);          return (oldval);
272  }  }
273    
274  #define ExtendBy        1024  #define ExtendBy        1024
275    
276  static char*  static char *
277  OutputValue(char *key, char *buf, int size)  OutputValue(char *key, char *buf, int size)
278  {  {
279          int                     i = 0;          int                     i = 0;
# Line 267  OutputValue(char *key, char *buf, int si Line 282  OutputValue(char *key, char *buf, int si
282          int                     slen = 0;          int                     slen = 0;
283    
284          size--;          size--;
285          for ( ; ; )          for (;;)
286          {          {
287                  switch (*key)                  switch (*key)
288                  {                  {
289                          case '\\':      subst ="\\\\";                          case '\\':
290                                                  slen = 2;                                  subst = "\\\\";
291                                                  break;                                  slen = 2;
292                          case '  ':      subst = "\\011";                                  break;
293                                                  slen = 4;                          case '  ':
294                                                  break;                                  subst = "\\011";
295                          case '\n':      subst = "\\012";                                  slen = 4;
296                                                  slen = 4;                                  break;
297                                                  break;                          case '\n':
298                          case '\'':      subst = "\\047";                                  subst = "\\012";
299                                                  slen = 4;                                  slen = 4;
300                                                  break;                                  break;
301                          case '\0':      out[i] = 0;                          case '\'':
302                                                  return(out);                                  subst = "\\047";
303                          default:        slen = 1;                                  slen = 4;
304                                                  break;                                  break;
305                            case '\0':
306                                    out[i] = 0;
307                                    return (out);
308                            default:
309                                    slen = 1;
310                                    break;
311                  }                  }
312    
313                  if (i + slen >= size)                  if (i + slen >= size)
314                  {                  {
315                          if (out == buf)                          if (out == buf)
316                          {                          {
317                                  out = (char*) palloc(size + ExtendBy);                                  out = (char *) palloc(size + ExtendBy);
318                                  strncpy(out, buf, i);                                  strncpy(out, buf, i);
319                                  size += ExtendBy;                                  size += ExtendBy;
320                          }                          }
321                          else                          else
322                          {                          {
323                                  out = (char*) repalloc(out, size + ExtendBy);                                  out = (char *) repalloc(out, size + ExtendBy);
324                                  size += ExtendBy;                                  size += ExtendBy;
325                          }                          }
326                  }                  }
# Line 314  OutputValue(char *key, char *buf, int si Line 335  OutputValue(char *key, char *buf, int si
335                  key++;                  key++;
336          }          }
337    
338          return(out);          return (out);
339    
340  }  }
341    
342    #ifdef PG_FUNCTION_INFO_V1
343    Datum
344    _rserv_xid_(PG_FUNCTION_ARGS)
345    #else
346    int32
347    _rserv_xid_(void)
348    #endif
349    {
350            int32   curr_xid = GetCurrentTransactionId();
351    
352            return (curr_xid);
353    }
354    

Legend:
Removed from v.1.1.1.1  
changed lines
  Added in v.1.5

  ViewVC Help
Powered by ViewVC 1.1.26