]> andersk Git - moira.git/blame - dbck/fix.dc
Initial revision
[moira.git] / dbck / fix.dc
CommitLineData
68bbc9c3 1/* $Header$
2 *
3 * User interface routines for dbck (Moira database consistency checker)
4 *
5 * (c) Copyright 1988 by the Massachusetts Institute of Technology.
6 * For copying and distribution information, please see the file
7 * <mit-copyright.h>.
8 */
9
10#include <mit-copyright.h>
11#include <moira.h>
12#include <stdio.h>
13#include "dbck.h"
14
208a4f4a 15EXEC SQL INCLUDE sqlca; /* SQL Communications Area */
16EXEC SQL INCLUDE sqlda; /* SQL Descriptor Area */
17
18#define SQLDA_RETVALS
19typedef IISQLDA_TYPE(DBCK_SQLDA,DBCK_SQLDA_T,SQLDA_RETVALS);
20DBCK_SQLDA_T SQLDA;
68bbc9c3 21
208a4f4a 22static char fix_qc_rcsid[] = "$Header$";
68bbc9c3 23
208a4f4a 24EXEC SQL BEGIN DECLARE SECTION;
25char *_table;
26char *_idfield;
27char stmt_buf[500];
28EXEC SQL END DECLARE SECTION;
68bbc9c3 29
208a4f4a 30generic_ffunc(id)
31EXEC SQL BEGIN DECLARE SECTION;
32int id;
33EXEC SQL END DECLARE SECTION;
34{
35 EXEC SQL BEGIN DECLARE SECTION;
36 int rowcount;
37 EXEC SQL END DECLARE SECTION;
68bbc9c3 38
208a4f4a 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);
68bbc9c3 45 if (rowcount > 0)
46 printf("%d entr%s deleted\n", rowcount, rowcount==1?"y":"ies");
47 else
48 printf("Not deleted\n");
49 modified(_table);
208a4f4a 50}
68bbc9c3 51
52
53generic_delete(sq, pfunc, table, idfield, preen)
54struct save_queue *sq;
55void (*pfunc)();
56char *table, *idfield;
57int preen;
58{
59 _table = table;
60 _idfield = idfield;
61 generic_fix(sq, pfunc, "Delete", generic_ffunc, preen);
62}
63
64
65single_delete(table, idfield, id)
66char *table, *idfield;
67int id;
68{
69 _table = table;
70 _idfield = idfield;
71 generic_ffunc(id);
72}
73
74
208a4f4a 75zero_fix(tbl, zrfield, idfield, id)
76EXEC SQL BEGIN DECLARE SECTION;
77char *tbl, *zrfield, *idfield;
78int id;
79EXEC SQL END DECLARE SECTION;
80{
81 EXEC SQL BEGIN DECLARE SECTION;
82 int rowcount;
83 EXEC SQL END DECLARE SECTION;
68bbc9c3 84
208a4f4a 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);
68bbc9c3 91 if (rowcount > 0)
92 printf("%d entr%s fixed\n", rowcount, rowcount==1?"y":"ies");
93 else
94 printf("Not fixed\n");
208a4f4a 95 modified(tbl);
96}
68bbc9c3 97
98
99int single_fix(msg, preen)
100char *msg;
101int preen;
102{
103 if (mode == MODE_PREEN)
104 return(preen);
105
106 switch (mode) {
107 case MODE_ASK:
108 if (!prompt(msg))
109 break;
110 case MODE_YES:
111 return(1);
112 break;
113 case MODE_NO:
114 ;
115 }
116 return(0);
117}
118
119
120generic_fix(sq, pfunc, msg, ffunc, preen)
121struct save_queue *sq;
122char *msg;
123int (*pfunc)(), (*ffunc)();
124int preen;
125{
126 int id;
127
128 while (sq_get_data(sq, &id)) {
129 if ((*pfunc)(id) == 0 && single_fix(msg, preen))
130 (*ffunc)(id);
131 }
132 sq_destroy(sq);
133}
134
135
136int prompt(msg)
137char *msg;
138{
139 char buf[BUFSIZ];
208a4f4a 140 EXEC SQL BEGIN DECLARE SECTION;
141 extern int dcmenable;
142 EXEC SQL END DECLARE SECTION;
68bbc9c3 143
144 while (1) {
145 printf("%s (Y/N/Q)? ", msg);
146 fflush(stdout);
147 gets(buf);
148 if (buf[0] == 'Y' || buf[0] == 'y')
149 return(1);
150 if (buf[0] == 'N' || buf[0] == 'n')
151 return(0);
152 if (buf[0] == 'Q' || buf[0] == 'q') {
153 if (prompt("Are you sure you want to quit")) {
154 if (prompt("Save database changes")) {
208a4f4a 155/* end transaction */
156 EXEC SQL COMMIT WORK;
68bbc9c3 157 cleanup();
158 exit(0);
159 } else {
208a4f4a 160/* abort */
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';
166/* exit */
167 /* No equivalent (?) */
68bbc9c3 168 exit(1);
169 }
170 }
171 }
172 }
173}
174
175
176/**
177 ** set_next_object_id - set next object id in values table
178 **
179 ** Inputs: object - object name in values table and in objects
180 ** table - name of table objects are found in
181 **
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
184 **
185 **/
186
208a4f4a 187int set_next_object_id(object, tablename)
68bbc9c3 188 char *object;
208a4f4a 189 char *tablename;
190{
191 EXEC SQL BEGIN DECLARE SECTION;
192 char *name, *tbl;
193 int rowcount, existence, value;
194 EXEC SQL END DECLARE SECTION;
68bbc9c3 195
196 name = object;
208a4f4a 197 tbl = tablename;
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
201 WHERE name = :name;
202 EXEC SQL INQUIRE_SQL(:rowcount = rowcount);
68bbc9c3 203 if (rowcount != 1)
204 return(MR_NO_ID);
205
208a4f4a 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;
210 if(sqlca.sqlcode)
211 return(MR_INTERNAL);
212 EXEC SQL DECLARE foo CURSOR FOR stmt;
213 EXEC SQL OPEN foo;
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;
217 EXEC SQL CLOSE foo;
218
68bbc9c3 219 if (rowcount != 1)
220 return(MR_NO_ID);
208a4f4a 221 while (existence) {
68bbc9c3 222 value++;
223 if (value > MAX_ID_VALUE)
224 value = MIN_ID_VALUE;
208a4f4a 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;
228 if(sqlca.sqlcode)
229 return(MR_INTERNAL);
230 EXEC SQL DECLARE bar CURSOR FOR stmt;
231 EXEC SQL OPEN bar;
232 EXEC SQL FETCH bar USING DESCRIPTOR :&SQLDA;
233 if (sqlca.sqlcode != 0) break;
234 EXEC SQL CLOSE bar;
68bbc9c3 235 }
208a4f4a 236 EXEC SQL CLOSE bar;
68bbc9c3 237
238 printf("setting ID %s to %d\n", name, value);
208a4f4a 239/* repeat replace v (#value = @value) where v.#name = @name */
240 EXEC SQL REPEATED UPDATE numvalues SET value = :value
241 WHERE name = :name;
68bbc9c3 242 modified("values");
243 return(MR_SUCCESS);
208a4f4a 244}
245
246
247generic_fix_id(tbl, idfield, txtfield, oldid, name)
248 EXEC SQL BEGIN DECLARE SECTION;
249 char *tbl;
250 char *idfield;
251 char *txtfield;
252 int oldid;
253 char *name;
254 EXEC SQL END DECLARE SECTION;
255{
256 EXEC SQL BEGIN DECLARE SECTION;
257 int rowcount, id, temp;
258 EXEC SQL END DECLARE SECTION;
259
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
266 */
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);
68bbc9c3 273 if (rowcount == 1)
274 printf("Fixed\n");
275 else
276 printf("Not fixed, rowcount = %d\n", rowcount);
208a4f4a 277 modified(tbl);
68bbc9c3 278 return(id);
208a4f4a 279}
This page took 0.12648 seconds and 5 git commands to generate.