StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
spinDbAPI.C
1 // $Id: spinDbAPI.C,v 1.1 2005/09/30 23:47:48 balewski Exp $
2 // Descripion: a kind of swiss army knife for spin databases
3 // Author: Jan Balewski (IUCF)
4 //
5 // Note: log info at the bottom now
6 //
7 #include "StDbManager.hh"
8 #include "StDbSql.hh"
9 #include "StDbConfigNode.hh"
10 #include "StDbTable.h"
11 #include "StDbXmlReader.h"
12 #include "StDbXmlWriter.h"
13 #include "StDbElementIndex.hh"
14 
15 #include <stdlib.h>
16 #include <stdio.h>
17 
18 #include <string.h>
19 #include <getopt.h>
20 #include <time.h>
21 #include <errno.h>
22 #include <unistd.h>
23 
24 
25 #include "SpinDbIO.h"
26 #include "spinDbAPI.h"
27 
28 
29 const char *cvsRevision="$Revision: 1.1 $";
30 const char *keyToEverything = "jas";
31 const char *dbTimeFormat[] = {
32  "%Y-%m-%d %H:%M:%S",
33  "%Y-%m-%d %H:%M",
34  "%Y-%m-%d",
35  "%s",
36  0
37 };
38 
39 
40 // global flags
41 enum SpinDbAction action = GetDB;
42 char *argv0 = NULL; // program name
43 char *dbPath = NULL;
44 char *dbTime = "now";
45 char *dbExpTime = NULL;
46 char *dbFile = NULL;
47 char *dbFlavor = "ofl";
48 char *dbComment = getenv("USER");
49 char *dbName = "Calibrations_rhic";
50 int dataOnlyMode = false;
51 int debugMode = false;
52 
53 static SpinDbIOBase *
54 getDbIO(const char *node, const int ndata) {
55 
56  SpinDbIOBase *dbIO=0;
57 
58  // dbIO = new SpinDbBXmaskIO(ndata);return (dbIO);//tmp
59  // =================== SPIN RELATED =================
60  if (!strncmp(node,"spinV124" ,SpinDbMaxDbPathLen))
61  dbIO = new SpinDbV124IO(ndata);
62  else if (!strncmp(node,"spinStar" ,SpinDbMaxDbPathLen))
63  dbIO = new SpinDbStarIO(ndata);
64  else if (!strncmp(node,"spinBXmask" ,SpinDbMaxDbPathLen))
65  dbIO = new SpinDbBXmaskIO(ndata);
66  // =================== OTHER ==========================
67  else {
68  fprintf(stderr,"table %s unknown to %s\n",node,argv0);
69  return(NULL);
70  }
71 
72  if(!dbIO) {
73  fprintf(stderr,"table %s unknown to %s\n",node,argv0);
74  return(NULL);
75  }
76  return(dbIO);
77 }
78 
79 
80 int
81 printTree(FILE *out, StDbConfigNode *node , int level=0)
82 {
83  static int items=0; // to count if we have found anything
84  if(node==NULL) return items;
85  for(int i=0;i<level;i++) fprintf(out,"\t");
86  // level 0 == database name, so skip it
87  if(level>0) fprintf(out,"%s/\n",node->printName());
88  if( node->hasData() ) {
89  StDbTableIter *ti = node->getStDbTableIter();
90  StDbTable *t = NULL;
91  while( ( t = ti->next() ) ) {
92  for(int i=0;i<=level;i++) fprintf(out,"\t");
93  fprintf(out,"%s",t->printName());
94  fprintf(out,":%s",t->getCstructName());
95  fprintf(out,"\n");
96  items++;
97  }
98  }
99  (void) printTree(out,node->getFirstChildNode(),level+1);
100  (void) printTree(out,node->getNextNode() ,level );
101  return items;
102 }
103 
104 
105 
106 void
107 printHistory(FILE *out, StDbManager *mgr, StDbTable *dbTab , SpinDbIOBase *io)
108 {
109  FILE *null = fopen("/dev/null","w");
110  int nRec=0;
111  time_t tUnix=getTimeStamp(dbTimeFormat,dbTime);
112  time_t tOld =-1;
113  fprintf(out,"\nRec BeginDate (BNL) UnixTime ValidPeriod Comment\n");
114  while( tUnix>=0) {
115  mgr->setRequestTime(tUnix);
116  int ret = mgr->fetchDbTable(dbTab);
117  if(ret>0) {
118  nRec++;
119  //printf("%d %d (%d)\n",dbTab->getTableSize(),io->getBytes(),ret);
120  io->setData(dbTab->GetTable());
121  io->write(null);
122  // time_t tdiff=(tOld>0) ? dbTab->getBeginTime()-tOld : 0;
123  time_t tdiff= dbTab->getEndTime()- dbTab->getBeginTime();
124  int sec = tdiff % 60; tdiff /= 60;
125  int min = tdiff % 60; tdiff /= 60;
126  int hour = tdiff % 24; tdiff /= 24;
127  int day = tdiff ;
128  char *tstr = new char[32];
129  time_t bt = dbTab->getBeginTime();
130  if(bt==tOld) break;
131  strftime(tstr,32,dbTimeFormat[0],localtime(&bt));
132  fprintf(out,"%-3d %.20s %d %6dday(s) %02d:%02d:%02d %s\n",
133  nRec, tstr, dbTab->getBeginTime(),
134  day,hour,min,sec, io->getComment());
135  io->resetData();
136  tOld = dbTab->getBeginTime();
137  }
138  fflush(out);
139  tUnix= dbTab->getEndTime();
140  if(tUnix>SpinDbMaxUnixTime) break;
141  }
142 
143 }
144 
145 
146 void
147 printConfig(FILE *out, StDbManager *mgr)
148 {
149  const char *eTime="entryTime";
150  const char *vKey ="versionKey";
151  char **var;
152  int len = 0;
153 
154  StDbSql* db = (StDbSql*)mgr->findDb(dbName);
155  MysqlDb& Db = db->Db;
156  StDbBuffer& buff = db->buff;
157 
158  Db<<"select "<< vKey << "," << eTime << " from Nodes where nodeType='Config'"<<endsql;
159 
160  while(Db.Output(&buff)){ // loop over rows
161  buff.ReadArray(var,len,vKey);
162  fprintf(out,"%s : ",*var);
163  buff.ReadArray(var,len,eTime);
164  fprintf(out,"%s ",fmtSqlTime(*var));
165  fprintf(out,"\n");
166  }
167  buff.Raz();
168  Db.Release();
169 }
170 
171 static char *
172 printVersion()
173 {
174  const int vLen = strlen(cvsRevision);
175  static char *vStr = new char[vLen];
176  strncpy(vStr,cvsRevision+1,vLen-1);
177  vStr[vLen-2]=0x00;
178  return(vStr);
179 
180 }
181 
182 
183 static void
184 usage(const char *message=NULL)
185 {
186  if (message) fprintf(stderr,"%s: %s\n",argv0,message);
187  fprintf(stderr,"usage: %s --path <path> [EXTRA_OPTIONS]\n",argv0);
188  fprintf(stderr," -D|--database <name> : data base to use (default %s)\n",dbName);
189  fprintf(stderr," -p|--path <path> : full path to the table\n");
190  fprintf(stderr," -t|--time <time> : sets query time (default: now)\n");
191  fprintf(stderr," -x|--expire <time> : sets query expiration time (default: forever)\n");
192  fprintf(stderr," -F|--flavor : set database flavor (default ofl)\n");
193  fprintf(stderr," -f|--file <file> : set file name for I/O (default: stdin/stdout)\n");
194  fprintf(stderr," -g|-r|--get|--read : get (read) data from database (default)\n");
195  fprintf(stderr," -s|-w|--set|--write : set (write) data to database\n");
196  fprintf(stderr," -c|--comment <txt> : set db comment (default user id)\n");
197  fprintf(stderr," -T|--tree : print config tree\n");
198  fprintf(stderr," -H|--history : print time line for node\n");
199  fprintf(stderr," -C|--config : print available config versions\n");
200  fprintf(stderr," -d|--dataonly : don't write #node/table line, just the data\n");
201  fprintf(stderr," -v|--verbose : set verbose mode on\n");
202  fprintf(stderr," -q|--quiet : set quiet mode on\n");
203 
204  fprintf(stderr," -h|--help : this short help\n");
205  fprintf(stderr," supported time formats (cf. man date):\n");
206  for(int i=0; dbTimeFormat[i]!=NULL ; i++ ) {
207  const int MLEN=128;
208  char tmpstr[MLEN];
209  time_t t = time(0);
210  strftime(tmpstr,MLEN,dbTimeFormat[i],gmtime(&t));
211  fprintf(stderr," %-20s e.g.: %s\n",dbTimeFormat[i],tmpstr);
212  }
213  fprintf(stderr,"%s\n",printVersion());
214  if(message) exit(-1);
215  return;
216 }
217 
218 //---------------------------------------------------------------------
219 //---------------------------------------------------------------------
220 //---------------------------------------------------------------------
221 int
222 main(int argc, char *argv[])
223 {
224  extern char *optarg;
225  int optInd = 0;
226  char optChar = 0;
227 
228  static struct option optLong[] = {
229  { "database" , 1 , 0 , 'D' },
230  { "path" , 1 , 0 , 'p' },
231  { "time" , 1 , 0 , 't' },
232  { "expiration" , 1 , 0 , 'x' },
233  { "flavor" , 1 , 0 , 'F' },
234  { "file" , 1 , 0 , 'f' },
235  { "get" , 0 , (int *)&action , GetDB },
236  { "read" , 0 , (int *)&action , GetDB },
237  { "set" , 0 , (int *)&action , SetDB },
238  { "write" , 0 , (int *)&action , SetDB },
239  { "tree" , 0 , (int *)&action , PrintTree },
240  { "history" , 0 , (int *)&action , PrintHistory },
241  { "config" , 0 , (int *)&action , PrintConfig },
242  { "comment" , 1 , 0 , 'c' },
243  { "verbose" , 0 , &verboseMode , true},
244  { "quiet" , 0 , &verboseMode , false},
245  { "dataonly" , 0 , &dataOnlyMode , true},
246  { "debug" , 0 , &debugMode , true},
247  { "help" , 0 , 0 , 'h' },
248  { 0, 0, 0, 0}
249  };
250 
251 
252  // arguments and init
253  argv0 = strrchr(argv[0],'/');
254  argv0 = ( argv0 == NULL ) ? argv[0] : ++argv0 ;
255 
256  while((optChar = getopt_long(argc,argv,"D:p:t:x:F:f:c:grswTHCdvqh",optLong,&optInd)) != EOF) {
257  switch(optChar) {
258  case 0 : break;
259  case 'D' : dbName = optarg; break;
260  case 'p' : dbPath = optarg; break;
261  case 't' : dbTime = optarg; break;
262  case 'x' : dbExpTime = optarg; break;
263  case 'F' : dbFlavor = optarg; break;
264  case 'f' : dbFile = optarg; break;
265  case 'r' : // same as g
266  case 'g' : action = GetDB; break;
267  case 'w' : // same as s
268  case 's' : action = SetDB; break;
269  case 'T' : action = PrintTree; break;
270  case 'H' : action = PrintHistory; break;
271  case 'C' : action = PrintConfig; break;
272  case 'c' : dbComment = optarg; break;
273  case 'd' : dataOnlyMode= true; break;
274  case 'v' : verboseMode = true; break;
275  case 'q' : quietMode = true; break;
276  case 'h' : usage(); return(0); break;
277  default : usage("unknown option"); break;
278  };
279  }
280  if(!dbPath && action!=PrintConfig ) usage("database path missing");
281 
282 
283  //
285  StDbConfigNode *dbNode = NULL;
286  StDbTable *dbTab = NULL;
287  char *node = NULL;
288  FILE *file = NULL;
289 
290  mgr->setVerbose(verboseMode);
291  mgr->setQuiet(quietMode);
292 
293  // sanity check
294  if( ! mgr->findDefaultServer() ) {
295  fprintf(stderr,"cannot find the default DB server\n");
296  return(-1);
297  }
298 
299  if(dbFile) {
300  file = fopen(dbFile,(action==SetDB) ? "r" : "w");
301  if(!file) {
302  fprintf(stderr,"%s: fopen '%s' failed, %s\n",argv0,dbFile,strerror(errno));
303  return(-1);
304  }
305  } else {
306  file = (action==SetDB) ? stdin : stdout;
307  }
308 
309  switch(action) {
310  case PrintTree:
311  node = node=strsep(&dbPath,"/");
312  if(node) {
313  dbNode = mgr->initConfig(dbName,node);
314  if(dbNode) {
315  if(verboseMode || !quietMode)
316  fprintf (file,"DATABASE TREE:\n");
317  fprintf (file,"%s/\n",node);
318  if(printTree(file,dbNode)<=0) {
319  fprintf (stderr,"config %s is empty\n",node);
320  }
321  }
322  }
323  return 0;
324  break;
325  case PrintConfig:
326  if(verboseMode || !quietMode)
327  fprintf(file,"DATABASE VERSIONS:\n");
328  printConfig(file,mgr);
329  return 0;
330  default:
331  break;
332  }
333 
334 
335  // parse database path
336  while( (node=strsep(&dbPath,"/")) != NULL ) {
337  StDbConfigNode *tn = (dbNode==NULL) ?
338  mgr->initConfig(dbName,node) : dbNode->findConfigNode(node);
339  if(!tn) break; // assume the last token is a db table
340  dbNode = tn;
341  dprintf(" database node: %p\n",node);
342  }
343 
344  if(!node) usage("invalid path");
345 
346  dbTab = dbNode->findTable(node);
347  if(!dbTab) { fprintf(stderr,"%s: table %s not found\n",argv0,node); return (-1); }
348 
349  dprintf("found table: %s\n",node);
350 
351  int nrows=dbTab->GetNRows();
352  int ndata=0;
353 
354  SpinDbIOBase *dbIO = getDbIO(node,nrows);
355  if(dbIO==NULL) return(-1);
356 
357  char keyLine[SpinDbMaxDbPathLen];
358  char keyBase[SpinDbMaxKeyLength];
359  time_t tUnix = getTimeStamp(dbTimeFormat,dbTime);
360  time_t tExpUnix = (dbExpTime!=NULL) ? getTimeStamp(dbTimeFormat,dbExpTime) : 0;
361 
362  dbTab->setFlavor(dbFlavor);
363  switch(action) {
364  case PrintHistory:
365  printHistory(file,mgr,dbTab,dbIO);
366  return 0;
367  break;
368  case SetDB:
369  fgets (keyLine,SpinDbMaxDbPathLen-1,file);
370  sprintf(keyBase,SpinDbKeyFormat,dbNode->printName(),node);
371  // printf("AAA=%s=\n",keyBase);
372  if(strstr(keyLine,keyBase)==0 && strcmp(keyLine,keyToEverything) ) {
373  fprintf(stderr,"signature mismatch: data file key '%s', required '%s'\n",
374  keyLine,keyBase);
375  return (-1);
376  }
377 
378  dbIO->setComment(dbComment);
379 
380  ndata = dbIO->read(file);
381  if(ndata<=0) {
382  fprintf(stderr,"%s: reading file %s failed\n",argv0,dbFile);
383  return(-1);
384  }
385  if(nrows>1) {
386  dbTab->SetTable(dbIO->getData(),ndata, dbIO->getIndices());
387  } else {
388  dbTab->SetTable(dbIO->getData(),ndata);
389  }
390  if(tExpUnix>0) {
391  dbTab->setEndStoreTime(tExpUnix);
392  fprintf(stderr,"%s: setting end time %ld\n",argv0,tExpUnix);
393  }
394  // fprintf(stderr,"TEST, terminated by hand DB-write, JB\n"); exit(1);
395  //mgr->setStoreTime(getTimeStamp(dbTimeFormat,dbTime));
396  mgr->setStoreTime(tUnix);
397  if(! mgr->storeDbTable(dbTab) ) {
398  fprintf(stderr,"%s: storing table %s failed\n",argv0,node);
399  return(-1);
400  }
401 
402  break;
403  case GetDB:
404  mgr ->setRequestTime(tUnix);
405  if( ! mgr->fetchDbTable(dbTab) ) {
406  fprintf(stderr,"%s: problem with fetch for time stamp %ld / %s",argv0,tUnix,ctime(&tUnix));
407  fprintf(stderr," There is no record for this table over the time period :\n");
408  fprintf(stderr," BeginDate = %s\t",dbTab->getBeginDateTime());
409  fprintf(stderr," EndDate = %s\n",dbTab->getEndDateTime());
410  fprintf(stderr," BeginTimeUnix = %d\t",dbTab->getBeginTime());
411  fprintf(stderr," EndTimeUnix = %d\n",dbTab->getEndTime());
412  return(-1);
413  }
414  if(! dbTab->GetTable() ) {
415  fprintf(stderr,"no data found in table %s\n",node);
416  return(-1);
417  }
418  dbIO->setData(dbTab->GetTable());
419 
420  if(verboseMode || !quietMode)
421  fprintf(stderr,"BNL Time Stamp Range from: %s to: %s \n",
422  fmtSqlTime(dbTab->getBeginDateTime()),fmtSqlTime(dbTab->getEndDateTime()));
423  if(!dataOnlyMode) {
424  fprintf(file,SpinDbKeyFormat,dbNode->printName(),node);
425  fprintf(file,"\n");
426  }
427  ndata = dbIO->write(file);
428  dbComment = dbIO->getComment();
429  if(verboseMode || !quietMode)
430  fprintf(stderr,"COMMENT: %s\n",dbComment);
431  break;
432  default:
433  break;
434  }
435 
436  if(ndata>0) {
437  dprintf("database access successful %d\n",ndata);
438  } else {
439  fprintf(stderr,"%s: table %s access failed\n",argv0,node);
440  }
441 
442 
443  fclose(file);
444  return 0;
445 }
446 
447 
448 // $Log: spinDbAPI.C,v $
449 // Revision 1.1 2005/09/30 23:47:48 balewski
450 // start
451 //
virtual void SetTable(char *data, int nrows, int *idList=0)
calloc&#39;d version of data for StRoot
Definition: StDbTable.cc:550
static StDbManager * Instance()
strdup(..) is not ANSI
Definition: StDbManager.cc:155