#include "mr_server.h"
EXEC SQL INCLUDE sqlca;
+EXEC SQL WHENEVER SQLERROR CALL ingerr;
+
extern char *whoami, *strsave();
extern int ingres_errno, mr_errcode;
* List
* String
* Machine
+ * Subnet
* Cluster
* Filesystem
* then we will have to rework the code that only looks at the first
int id;
struct item *next;
struct item *prev;
+ struct item *trans; /* keep track of transactions */
};
static struct item cachehead;
if (cachehead.prev != &cachehead)
free(cachehead.prev);
cachehead.next = cachehead.prev = &cachehead;
+ cachehead.trans = (struct item *)NULL;
}
char *type;
int *id;
{
- register struct item *i;
+ register struct item *i, *t;
EXEC SQL BEGIN DECLARE SECTION;
char *iname;
int j, rowcount;
EXEC SQL END DECLARE SECTION;
+ char key;
int h, ctr;
h = hashname(name, type);
cachemisses++;
iname = name;
+ key = *type;
- switch (*type) {
+ if (!strcasecmp(type, "subnet"))
+ key = 'N';
+
+ switch (key) {
case 'U':
case 'u':
+ if (index(iname, '@') || (strlen(iname) > 8)) {
+ sqlca.sqlcode = 100;
+ break;
+ }
EXEC SQL SELECT users_id INTO :j FROM users WHERE login=:iname;
break;
case 'L':
break;
case 'M':
case 'm':
- uppercase(iname);
- EXEC SQL SELECT mach_id INTO :j FROM machine WHERE name=:iname;
+ EXEC SQL SELECT mach_id INTO :j FROM machine WHERE name=UPPERCASE(:iname);
+ break;
+ case 'N':
+ case 'n':
+ EXEC SQL SELECT snet_id INTO :j FROM subnet WHERE name=UPPERCASE(:iname);
break;
case 'C':
case 'c':
i->prev = &cachehead;
cachehead.next->prev = i;
cachehead.next = i;
+ /* find the end of the transaction chain & add this item */
+ for (t = &cachehead; t->trans && t != i; t = t->trans);
+ if (t != i) {
+ t->trans = i;
+ i->trans = (struct item *)NULL;
+ }
return(MR_SUCCESS);
}
char *type;
char **name;
{
- register struct item *i;
+ register struct item *i, *t;
EXEC SQL BEGIN DECLARE SECTION;
char iname[NAMESZ];
int j, rowcount;
EXEC SQL END DECLARE SECTION;
+ char key;
int ctr;
for (i = cachehead.next; i != &cachehead; i = i->next) {
cachemisses++;
j = id;
+ key = *type;
+ if (!strcasecmp(type, "subnet"))
+ key = 'N';
- switch (*type) {
+ switch (key) {
case 'U':
case 'u':
- EXEC SQL SELECT login INTO :iname FROM users WHERE users_id=:j;
+ EXEC SQL SELECT CHAR(login) INTO :iname FROM users WHERE users_id=:j;
break;
case 'L':
case 'l':
- EXEC SQL SELECT name INTO :iname FROM list WHERE list_id=:j;
+ EXEC SQL SELECT CHAR(name) INTO :iname FROM list WHERE list_id=:j;
break;
case 'M':
case 'm':
- EXEC SQL SELECT name INTO :iname FROM machine WHERE mach_id=:j;
+ EXEC SQL SELECT CHAR(name) INTO :iname FROM machine WHERE mach_id=:j;
+ break;
+ case 'N':
+ case 'n':
+ EXEC SQL SELECT CHAR(name) INTO :iname FROM subnet WHERE snet_id=:j;
break;
case 'C':
case 'c':
- EXEC SQL SELECT name INTO :iname FROM cluster WHERE clu_id=:j;
+ EXEC SQL SELECT CHAR(name) INTO :iname FROM cluster WHERE clu_id=:j;
break;
case 'F':
case 'f':
- EXEC SQL SELECT label INTO :iname FROM filesys WHERE filsys_id=:j;
+ EXEC SQL SELECT CHAR(label) INTO :iname FROM filesys WHERE filsys_id=:j;
break;
case 'S':
case 's':
- EXEC SQL SELECT string INTO :iname FROM strings WHERE string_id=:j;
+ EXEC SQL SELECT CHAR(string) INTO :iname FROM strings WHERE string_id=:j;
break;
default:
return(MR_INTERNAL);
i->prev = &cachehead;
cachehead.next->prev = i;
cachehead.next = i;
+ /* find the end of the transaction chain & add this item */
+ for (t = &cachehead; t->trans && t != i; t = t->trans);
+ if (t != i) {
+ t->trans = i;
+ i->trans = (struct item *)NULL;
+ }
return(MR_SUCCESS);
}
char *type;
int id;
{
- register struct item *i;
+ register struct item *i, *t;
for (i = cachehead.next; i != &cachehead; i = i->next)
- if (i->id == id && !strcmp(i->type, type))
- return(MR_SUCCESS);
+ if (i->id == id && !strcmp(i->type, type)) {
+ if (strcmp(i->name, name)) {
+ strcpy(i->name, name);
+ i->nhash = hashname(name, type);
+ }
+ return(MR_SUCCESS);
+ }
if (cachesize < CACHESIZE) {
i = (struct item *) malloc(sizeof(struct item));
cachesize++;
i->prev = &cachehead;
cachehead.next->prev = i;
cachehead.next = i;
+ /* find the end of the transaction chain & add this item */
+ for (t = &cachehead; t->trans && t != i; t = t->trans);
+ if (t != i) {
+ t->trans = i;
+ i->trans = (struct item *)NULL;
+ }
return(MR_SUCCESS);
}
}
}
}
+
+
+/* Called when a transaction is committed to also commit any cache changes.
+ * Just throws away the list of cache changes for this transaction.
+ */
+
+cache_commit()
+{
+ cachehead.trans = (struct item *)NULL;
+}
+
+
+/* Called whan a transaction is aborted to throw away any cache changes
+ * from that transaction.
+ */
+
+cache_abort()
+{
+ register struct item *i, *t;
+
+ for (i = cachehead.trans; i; i = t) {
+ t = i->trans;
+ flush_name(i->name, i->type);
+ }
+ cachehead.trans = (struct item *)NULL;
+}