3 * User interface routines for dbck (Moira database consistency checker)
5 * (c) Copyright 1988 by the Massachusetts Institute of Technology.
6 * For copying and distribution information, please see the file
10 #include <mit-copyright.h>
15 EXEC SQL INCLUDE sqlca; /* SQL Communications Area */
16 EXEC SQL INCLUDE sqlda; /* SQL Descriptor Area */
19 typedef IISQLDA_TYPE(DBCK_SQLDA,DBCK_SQLDA_T,SQLDA_RETVALS);
22 static char fix_qc_rcsid[] = "$Header$";
24 EXEC SQL BEGIN DECLARE SECTION;
28 EXEC SQL END DECLARE SECTION;
31 EXEC SQL BEGIN DECLARE SECTION;
33 EXEC SQL END DECLARE SECTION;
35 EXEC SQL BEGIN DECLARE SECTION;
37 EXEC SQL END DECLARE SECTION;
39 /* delete _table where _table._idfield = id */
40 sprintf(stmt_buf,"DELETE FROM %s WHERE %s.%s = %d",
41 _table,_table,_idfield,id);
42 EXEC SQL EXECUTE IMMEDIATE :stmt_buf;
43 /* inquire_equel(rowcount = "rowcount") */
44 EXEC SQL INQUIRE_SQL(:rowcount = rowcount);
46 printf("%d entr%s deleted\n", rowcount, rowcount==1?"y":"ies");
48 printf("Not deleted\n");
53 generic_delete(sq, pfunc, table, idfield, preen)
54 struct save_queue *sq;
56 char *table, *idfield;
61 generic_fix(sq, pfunc, "Delete", generic_ffunc, preen);
65 single_delete(table, idfield, id)
66 char *table, *idfield;
75 zero_fix(tbl, zrfield, idfield, id)
76 EXEC SQL BEGIN DECLARE SECTION;
77 char *tbl, *zrfield, *idfield;
79 EXEC SQL END DECLARE SECTION;
81 EXEC SQL BEGIN DECLARE SECTION;
83 EXEC SQL END DECLARE SECTION;
85 /* replace tbl (zrfield = 0) where table.idfield = id */
86 sprintf(stmt_buf,"UPDATE %s SET %d = 0 WHERE %s.%s = %d",
87 tbl,zrfield,tbl,idfield,id);
88 EXEC SQL EXECUTE IMMEDIATE :stmt_buf;
89 /* inquire_equel(rowcount = "rowcount") */
90 EXEC SQL INQUIRE_SQL(:rowcount = rowcount);
92 printf("%d entr%s fixed\n", rowcount, rowcount==1?"y":"ies");
94 printf("Not fixed\n");
99 int single_fix(msg, preen)
103 if (mode == MODE_PREEN)
120 generic_fix(sq, pfunc, msg, ffunc, preen)
121 struct save_queue *sq;
123 int (*pfunc)(), (*ffunc)();
128 while (sq_get_data(sq, &id)) {
129 if ((*pfunc)(id) == 0 && single_fix(msg, preen))
140 EXEC SQL BEGIN DECLARE SECTION;
141 extern int dcmenable;
142 EXEC SQL END DECLARE SECTION;
145 printf("%s (Y/N/Q)? ", msg);
148 if (buf[0] == 'Y' || buf[0] == 'y')
150 if (buf[0] == 'N' || buf[0] == 'n')
152 if (buf[0] == 'Q' || buf[0] == 'q') {
153 if (prompt("Are you sure you want to quit")) {
154 if (prompt("Save database changes")) {
155 /* end transaction */
156 EXEC SQL COMMIT WORK;
161 EXEC SQL ROLLBACK WORK;
162 /* replace values (value = dcmenable)
163 * where values.name = "dcm_enable" */
164 EXEC SQL UPDATE numvalues SET value = :dcmenable
165 WHERE name='dcm_enable';
167 /* No equivalent (?) */
177 ** set_next_object_id - set next object id in values table
179 ** Inputs: object - object name in values table and in objects
180 ** table - name of table objects are found in
182 ** - called before an APPEND operation to set the next object id to
183 ** be used for the new record to the next free value
187 int set_next_object_id(object, tablename)
191 EXEC SQL BEGIN DECLARE SECTION;
193 int rowcount, existence, value;
194 EXEC SQL END DECLARE SECTION;
198 /* range of v is values
199 * repeat retrieve (value = v.#value) where v.#name = @name */
200 EXEC SQL REPEATED SELECT value INTO :value FROM numvalues
202 EXEC SQL INQUIRE_SQL(:rowcount = rowcount);
206 /* retrieve (existence = any(tbl.name where tbl.name = value)) */
207 SQLDA.sqlvar[0].sqldata=(void *)&rowcount;
208 sprintf(stmt_buf,"SELECT COUNT (*) FROM %s WHERE %s=%d",tbl,name,value);
209 EXEC SQL PREPARE stmt INTO :&SQLDA USING NAMES FROM :stmt_buf;
212 EXEC SQL DECLARE foo CURSOR FOR stmt;
214 EXEC SQL FETCH foo USING DESCRIPTOR :&SQLDA;
215 if (sqlca.sqlcode < 0) return(MR_INTERNAL);
216 if (sqlca.sqlcode == 100) existence=0; else existence=1;
223 if (value > MAX_ID_VALUE)
224 value = MIN_ID_VALUE;
225 /* retrieve (existence = any(tbl.name where tbl.name = value)) */
226 sprintf(stmt_buf,"SELECT %s FROM %s WHERE %s=%d",name,tbl,name,value);
227 EXEC SQL PREPARE stmt INTO :&SQLDA USING NAMES FROM :stmt_buf;
230 EXEC SQL DECLARE bar CURSOR FOR stmt;
232 EXEC SQL FETCH bar USING DESCRIPTOR :&SQLDA;
233 if (sqlca.sqlcode != 0) break;
238 printf("setting ID %s to %d\n", name, value);
239 /* repeat replace v (#value = @value) where v.#name = @name */
240 EXEC SQL REPEATED UPDATE numvalues SET value = :value
247 generic_fix_id(tbl, idfield, txtfield, oldid, name)
248 EXEC SQL BEGIN DECLARE SECTION;
254 EXEC SQL END DECLARE SECTION;
256 EXEC SQL BEGIN DECLARE SECTION;
257 int rowcount, id, temp;
258 EXEC SQL END DECLARE SECTION;
260 set_next_object_id(tbl, idfield);
261 /* retrieve (id = values.value) where values.#name = idfield */
262 EXEC SQL SELECT value INTO :id FROM numvalues
263 WHERE name = :idfield;
264 /* replace tbl (idfield = values.value) where values.#name = idfield and
265 * tbl.idfield = oldid and tbl.txtfield = name
267 EXEC SQL SELECT value INTO :temp FROM numvalues
268 WHERE name = :idfield;
269 sprintf(stmt_buf,"UPDATE %s SET %s = %d WHERE %s=%d AND %s='%s'",
270 tbl,idfield,temp,idfield,oldid,txtfield,name);
271 EXEC SQL EXECUTE IMMEDIATE :stmt_buf;
272 EXEC SQL INQUIRE_SQL(:rowcount = rowcount);
276 printf("Not fixed, rowcount = %d\n", rowcount);