]> andersk Git - moira.git/blobdiff - server/qrtn.qc
Avoid aborting a transaction that has been deadlocked; and
[moira.git] / server / qrtn.qc
index dac7e9243d6f5e0749944407ec53e997a69c1d7f..12bbfa1d7013bbae91597a5b369ee4a23f53d653 100644 (file)
@@ -16,10 +16,14 @@ static char *rcsid_qrtn_qc = "$Header$";
 
 char *Argv[16];
 
-static int ingres_errno = 0;
+int ingres_errno = 0;
 extern char *whoami;
 extern FILE *journal;
 
+#define INGRES_BAD_INT 4111
+#define INGRES_BAD_DATE 4302
+#define INGRES_DEADLOCK 4700
+
 /*
  * ingerr: (supposedly) called when Ingres indicates an error.
  * I have not yet been able to get this to work to intercept a
@@ -29,9 +33,25 @@ extern FILE *journal;
 static int ingerr(num)
     int *num;
 {
-    ingres_errno = SMS_INGRES_ERR;
-    com_err(whoami, SMS_INGRES_ERR, " code %d\n", ingres_errno);
-    return *num;
+    char buf[256];
+
+    switch (*num) {
+    case INGRES_BAD_INT:
+       ingres_errno = SMS_INTEGER;
+       break;
+    case INGRES_BAD_DATE:
+       ingres_errno = SMS_DATE;
+       break;
+    case INGRES_DEADLOCK:
+       ingres_errno = SMS_DEADLOCK;
+       break;
+    default:
+       ingres_errno = SMS_INGRES_ERR;
+       com_err(whoami, SMS_INGRES_ERR, " code %d\n", *num);
+       critical_alert("SMS", "SMS server encountered INGRES ERROR %d", *num);
+       return (*num);
+    }
+    return (0);
 }
 
 int sms_open_database()
@@ -49,6 +69,7 @@ int sms_open_database()
        
     /* open the database */
 ##  ingres sms
+##  set lockmode session where readlock = exclusive
     return ingres_errno;
 }
 
@@ -116,6 +137,7 @@ sms_process_query(cl, name, argc, argv_ro, action, actarg)
     if (q == (struct query *)0) return(SMS_NO_HANDLE);
     v = q->validate;
 
+    ingres_errno = 0;
     if (q->type != RETRIEVE)
 ##      begin transaction
 
@@ -171,9 +193,6 @@ sms_process_query(cl, name, argc, argv_ro, action, actarg)
                status = do_retrieve(q, pqual, psort, action, actarg);
            }
            if (status != SMS_SUCCESS) break;
-           table = q->rtable;
-##          repeat replace tblstats (retrieves = tblstats.retrieves + 1)
-##                 where tblstats.#table = @table
        } else {
            status = (*v->post_rtn)(q, Argv, cl, action, actarg);
        }
@@ -194,9 +213,11 @@ sms_process_query(cl, name, argc, argv_ro, action, actarg)
            status = do_update(q, &Argv[q->argc], qual, action, actarg);
            if (status != SMS_SUCCESS) break;
            table = q->rtable;
-##         repeat replace tblstats (updates = tblstats.updates + 1,
-##                                  modtime = "now")
-##             where tblstats.#table = @table
+           if (strcmp(q->shortname, "sshi") && strcmp(q->shortname, "ssif")) {
+##             repeat replace tblstats (updates = tblstats.updates + 1,
+##                                      modtime = "now")
+##                 where tblstats.#table = @table
+           }
        }
 
        /* execute followup routine (if any) */
@@ -288,7 +309,9 @@ out:
                fflush(journal);
            }
        } else {
-##          abort              /* it never happened */
+           if (status != SMS_DEADLOCK) {
+##             abort           /* it never happened */
+           }
        }
     }
 
@@ -513,6 +536,10 @@ get_client(cl, client_type, client_id)
     int child;
     struct save_queue *sq_create();
 
+    if (!strcmp(strtrim(list_type), strtrim(member_type)) &&
+       list_id == member_id)
+       return(1);
+
     /* see if client is a direct member of list */
 ##  repeat retrieve (exists = any(m.#member_id where 
 ##                               m.#list_id = @list_id and
@@ -652,7 +679,10 @@ do_update(q, argv, qual, action, actarg)
 ##  where cqual
 
 ##  inquire_equel (errorno = "errorno")
-    if (errorno != 0) return(SMS_INGRES_ERR);
+    if (errorno == INGRES_BAD_INT)
+       return(SMS_INTEGER);
+    else if (errorno != 0)
+       return(SMS_INGRES_ERR);
     return(SMS_SUCCESS);
 ##}
 
@@ -680,7 +710,10 @@ do_append(q, argv, pqual, action, actarg)
     }
 
 ##  inquire_equel (errorno = "errorno")
-    if (errorno != 0) return(SMS_INGRES_ERR);
+    if (errorno == INGRES_BAD_INT)
+       return(SMS_INTEGER);
+    else if (errorno != 0)
+       return(SMS_INGRES_ERR);
     return(SMS_SUCCESS);
 ##}
 
@@ -732,20 +765,23 @@ set_next_object_id(object, table)
 ##  repeat retrieve (value = v.#value) where v.#name = @name
 ##  inquire_equel(rowcount = "rowcount")
     if (rowcount != 1)
-       return(SMS_INGRES_ERR);
+       return(SMS_NO_ID);
 
 ##  retrieve (exists = any(tbl.name where tbl.name = value))
 ##  inquire_equel(rowcount = "rowcount")
     if (rowcount != 1)
-       return(SMS_INGRES_ERR);
+       return(SMS_NO_ID);
     while (exists) {
        value++;
+       if (value > MAX_ID_VALUE)
+           value = MIN_ID_VALUE;
 ##     retrieve (exists = any(tbl.name where tbl.name = value))
     }
 
     if (LOG_RES)
         com_err(whoami, 0, "setting ID %s to %d", name, value);
 ##  repeat replace v (#value = @value) where v.#name = @name
+    if (ingres_errno != 0) return(ingres_errno);
     return(SMS_SUCCESS);
 ##}
 
This page took 0.039964 seconds and 4 git commands to generate.