check_database._pike
Go to the documentation of this file.
1 /* Copyright (C) 2000-2004 Thomas Bopp, Thorsten Hampel, Ludger Merkens
2  *
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation; either version 2 of the License, or
6  * (at your option) any later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * $Id: check_database.pike,v 1.1 2008/03/31 13:39:57 exodusd Exp $
18  */
19 class check_database {
20 public:
21 
22 
23 
24 string db_connect;
25 string config_file = "config/config.txt.steam";
26 Sql.Sql handle;
27 
28 int naming = 0;
29 int verbose = 0;
30 int analyse = 1;
31 
32 #define NEED_ARGS(s) if (!arg) { write("--"+(string)s+" needs an argument passed\n");return;}
33 
34 int get_variable(string name)
35 {
36  object res;
37  res = db()->big_query("select value from variables where "+
38  "var =\""+name+"\"");
39  if (objectp(res) && res->num_rows())
40  return (int) res->fetch_row()[0];
41 
42  return 0;
43 }
44 
45 string read_config(string filename, string param)
46 {
47  string config = Stdio.read_file(filename);
48  string acc_str;
49  sscanf(config, "%*s<"+param+">%s</"+param+">%*s", acc_str);
50  if (verbose)
51  write(sprintf("reading config file %s accessing %s\n",
52  filename, acc_str));
53  return acc_str;
54 }
55 
56 Sql.Sql db() {
57  if (objectp(handle))
58  return handle;
59  handle = Sql.Sql(db_connect);
60  return handle;
61 }
62 
63 
64 int detect() {
65  int iObjectsId = get_variable("#objects");
66  int status = 0;
67 
68  // check for existing differing tables
69  if (sizeof(db()->list_tables("i_"+(string)iObjectsId)))
70  status |= 1;
71  if (sizeof(db()->list_tables("i_objects")))
72  status |= 2;
73 
74  // we have both objects and i_oid_alias
75  if (status == 3)
76  {
77  Sql.sql_result
78  res = db()->big_query("select v from i_objects "+
79  "where k=\"rootroom\"");
80  string id_objects = res->fetch_row()[0];
81  res = db()->big_query("select v from i_"+
82  (string)iObjectsId+" where k="+
83  "\"rootroom\"");
84  string id_ioid = res->fetch_row()[0];
85 
86  if ( ((int) id_objects[1..]) < ((int) id_ioid[1..]))
87  {
88  naming = 1;
89  status = 4;
90  }
91  else
92  status = 5;
93  }
94 
95  if (verbose)
96  write(sprintf("Object ID of module objects is %d status %d\n",
97  iObjectsId, status));
98  // i_objects found without alternatives, thus naming is 1, but are
99  // there other strange modules?
100  if (status == 2)
101  {
102  naming = 1;
103  Sql.sql_result res =
104  db()->big_query("select var, value from variables where var "+
105  "like \"#%\"");
106  string var, value;
107  mixed vec;
108  while (vec = res->fetch_row())
109  {
110  [var, value] = vec;
111  if (sizeof(db()->list_tables("i_"+value)))
112  return 6; // at least one module with aliases
113  }
114  }
115  return status;
116 }
117 
118 
119 
120 
121 void main(int argc, array argv)
122 {
123  for (int i=1;i <sizeof(argv); i++) {
124  string cmd, arg;
125  if (sscanf(argv[i], "--%s=%s", cmd, arg) ==2 ||
126  sscanf(argv[i], "--%s", cmd))
127  {
128  switch (cmd) {
129  case "detect" :
130  if (!db_connect)
131  db_connect = read_config(config_file,"database");
132  switch (detect()) {
133  case 0:
134  write("no tables found -> unable to repair!\n");
135  break;
136  case 1:
137  write("no table i_objects -> rename i_oid tables.\n");
138  break;
139  case 2:
140  write("i_objects exists and there is no alternative "+
141  "table -> everything seems to be ok!\n");
142  break;
143  case 3:
144  write("huh? differing tables exist, but couldn't "+
145  "decide.\n");
146  break;
147  case 4:
148  write("differing tables found i_objects seems to be "+
149  "the original -> deleting i_oid files.\n");
150  write(sprintf("naming %d\n",naming));
151  break;
152  case 5:
153  write("differing tables found i_oid seems to be "+
154  "the original -> moving values.\n");
155  case 6:
156  write("i_objects exists and has no alternative, but "+
157  "there are other broken modules.\n");
158  break;
159  }
160  return;
161  case "db":
162  case "database":
163  NEED_ARGS("database");
164  db_connect = arg;
165  break;
166  case "with-config":
167  NEED_ARGS("with-config");
168  config_file = arg;
169  case "auto":
170  db_connect = read_config(config_file,"database");
171  break;
172  case "verbose":
173  case "v":
174  verbose = 1;
175  break;
176  case "fix":
177  analyse = 0;
178  break;
179  }
180  }
181  }
182 
183  if (!db_connect)
184  db_connect = read_config(config_file, "database");
185 
186  detect();
187 
188  Sql.sql_result modules =
189  db()->big_query("select var, value from variables where var "+
190  "like \"#%\"");
191 
192  string var, value;
193  mixed vec;
194  array temp = ({ ({ "#modules", "0" }) });
195  while (vec = modules->fetch_row())
196  temp += ({ vec });
197 
198  foreach (temp, vec)
199  {
200  int status = 0;
201  [var, value] = vec;
202  if (search(db()->list_tables("i_"+value), "i_"+value)!=-1)
203  status |=1;
204  if (search(db()->list_tables("i_"+var[1..]), "i_"+var[1..])!=-1)
205  status |=2;
206 
207  switch (status) {
208  case 1:
209  write(sprintf("rename i_%s to i_%s\n", value, var[1..]));
210  if (!analyse)
211  {
212  db()->big_query(sprintf("alter table i_%s rename to i_%s",
213  value, var[1..]));
214  }
215  break;
216  case 2:
217  write(sprintf("keep i_%s\n", var[1..]));
218  break;
219  case 3:
220  if (naming ==1) // heuristics is from table i_objects
221  {
222  write(sprintf("conflict keep i_%s and "+
223  "delete i_%s\n",
224  var[1..], value));
225  if (!analyse)
226  {
227  db()->big_query(sprintf("drop table i_%s", value));
228  }
229  }
230  else
231  {
232  write(sprintf("conflict move values from i_%s to"+
233  " i_%s\n", value, var[1..]));
234  if (!analyse)
235  {
236  db()->big_query(sprintf("drop table i_%s", var[1..]));
237  db()->big_query(sprintf("alter table i_%s rename "+
238  "to i_%s", value, var[1..]));
239  }
240  }
241  break;
242  }
243 
244  }
245 }
246 
247 
248 
249 };