source: branches/prototype-v0/zoo-project/zoo-kernel/sqlapi.c @ 822

Last change on this file since 822 was 822, checked in by djay, 7 years ago

Commit the minimal requirements for remote HPC support

  • Property svn:keywords set to Id
File size: 16.5 KB
Line 
1/*
2 * Authors : David Saggiorato
3 *           Gérald Fenoy
4 *  Copyright 2015 GeoLabs SARL. All rights reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24
25#include "ogr_api.h"
26#include "ogrsf_frmts.h"
27#include "ogr_p.h"
28#include "response_print.h"
29#if GDAL_VERSION_MAJOR >= 2
30#include <gdal_priv.h>
31#endif
32
33#include "sqlapi.h"
34#include <fcgi_stdio.h>
35#include <stdlib.h>
36
37/**
38 * Global GDALDataset pointer
39 */
40#if GDAL_VERSION_MAJOR >=2
41GDALDataset
42#else
43OGRDataSource
44#endif
45 *zoo_DS = NULL;
46
47/**
48 * Global OGRLayer pointer pointing to the lastest result set
49 */
50OGRLayer *zoo_ResultSet = NULL;
51
52/**
53 * Create a GDAL / OGR string for connecting to a db backend defined in the
54 * key section.
55 *
56 * @param conf the maps containing the setting of the main.cfg file
57 * @param key the name of the section containing the connection setting
58 * @return the OGR connection string
59 */
60char* _createInitString(maps* conf,const char* key){
61  char* res=NULL;
62  char keywords[6][14]={
63    "dbname",
64    "host",
65    "port",
66    "user",
67    "password",
68    "active_schema"   
69  };
70  int i=0;
71  maps* cconf=getMaps(conf,key);
72  int len=0;
73  for(i=0;i<6;i++){
74    map* tmp=getMap(cconf->content,keywords[i]);
75    fprintf(stderr,"%s %d \n",__FILE__,__LINE__);
76    fflush(stderr);
77    if(tmp!=NULL){
78      fprintf(stderr,"%s %d \n",__FILE__,__LINE__);
79      fflush(stderr);
80      if(res==NULL){
81        res=(char*)malloc((strlen(keywords[i])+strlen(tmp->value)+4)*sizeof(char));
82        sprintf(res,"%s='%s'",keywords[i],tmp->value);
83        len+=strlen(res);
84      }else{
85        char* res1=(char*)malloc((strlen(keywords[i])+strlen(tmp->value)+5)*sizeof(char));
86        sprintf(res1," %s='%s'",keywords[i],tmp->value);
87        res=(char*)realloc(res,(len+strlen(keywords[i])+strlen(tmp->value)+5)*sizeof(char));
88        memcpy(res+len,res1,(strlen(keywords[i])+strlen(tmp->value)+5)*sizeof(char));
89        len+=strlen(res1);
90        res[len]=0;
91        fprintf(stderr,"%s %d \n",__FILE__,__LINE__);
92        fflush(stderr);
93        free(res1);
94      }
95    }
96    fprintf(stderr,"%s %d \n",__FILE__,__LINE__);
97    fflush(stderr);
98  }
99  fprintf(stderr,"%s %d \n",__FILE__,__LINE__);
100  fflush(stderr);
101  map* tmp=getMap(cconf->content,"type");
102  if(tmp!=NULL){
103    char* fres=(char*)malloc((strlen(res)+strlen(tmp->value)+2)*sizeof(char));
104    sprintf(fres,"%s:%s",tmp->value,res);
105    free(res);
106    return fres;
107  }
108  return res;
109}
110
111/**
112 * Create a GDAL / OGR string for connecting to the db backend
113 *
114 * @param conf the maps containing the setting of the main.cfg file
115 * @return the OGR connection string
116 */
117char* createInitString(maps* conf){
118  return _createInitString(conf,"database");
119}
120
121/**
122 * Connect to a db backend.
123 *
124 * @param conf the maps containing the setting of the main.cfg file
125 * @see createInitString
126 */
127void _init_sql(maps* conf,const char* key){
128  char* sqlInitString=_createInitString(conf,key);
129  OGRSFDriver *poDriver = NULL;
130  OGRRegisterAll();
131
132#if GDAL_VERSION_MAJOR >= 2
133  zoo_DS = (GDALDataset*) GDALOpenEx( sqlInitString,
134                                      GDAL_OF_UPDATE | GDAL_OF_VECTOR,
135                                      NULL, NULL, NULL );
136#else
137  zoo_DS = OGRSFDriverRegistrar::Open(sqlInitString,false,&poDriver);
138#endif
139  if( zoo_DS == NULL ){
140#ifdef DEBUG
141    fprintf(stderr,"sqlInitString: %s FAILED !\n",sqlInitString);
142    fflush(stderr);
143#endif
144    free(sqlInitString);
145    setMapInMaps(conf,"lenv","message","Failed to connect to the database backend");
146    return;
147  }
148#ifdef DEBUG
149  fprintf(stderr,"sqlInitString: %s SUCEED !\n",sqlInitString);
150  fflush(stderr);
151#endif
152  free(sqlInitString);
153}
154
155/**
156 * Connect to the db backend.
157 *
158 * @param conf the maps containing the setting of the main.cfg file
159 * @see createInitString
160 */
161void init_sql(maps* conf){
162  return _init_sql(conf,"database");
163}
164
165/**
166 * Close any connection to the db backend.
167 *
168 * @param conf the maps containing the setting of the main.cfg file
169 */
170void close_sql(maps* conf){
171  if( zoo_ResultSet != NULL )
172    zoo_DS->ReleaseResultSet( zoo_ResultSet );
173  if(zoo_DS!=NULL){
174#if GDAL_VERSION_MAJOR >= 2
175    GDALClose(zoo_DS);
176#else
177    OGRDataSource::DestroyDataSource( zoo_DS );
178#endif
179    zoo_DS=NULL;
180  }
181}
182
183/**
184 * Call OGRCleanupAll.
185 *
186 */
187void end_sql(){
188  OGRCleanupAll();
189}
190
191/**
192 * Fetch a tuple set by executing a SQL query to the Database Backend.
193 *
194 * @param conf the maps containing the setting of the main.cfg file
195 * @param sqlQuery the SQL query to run
196 * @return NULL in case of failure or an OGRLayer pointer if the query succeed.
197 */
198OGRLayer *fetchSql(maps* conf,const char* sqlQuery){
199  OGRLayer *res=NULL;
200  res = zoo_DS->ExecuteSQL( sqlQuery, NULL, NULL);
201  return res;
202}
203
204void cleanFetchSql(maps* conf,OGRLayer *objects){
205  if( objects != NULL ){
206    zoo_DS->ReleaseResultSet( objects );
207    objects=NULL;
208  }
209}
210
211/**
212 * Execute a SQL query to the SQL Database Backend.
213 *
214 * @param conf the maps containing the setting of the main.cfg file
215 * @param sqlQuery the SQL query to run
216 * @return -1 in case of failure and 1 if the query succeed.
217 */
218int execSql(maps* conf,const char* sqlQuery){
219  int res=-1;
220  zoo_ResultSet = zoo_DS->ExecuteSQL( sqlQuery, NULL, NULL);
221  if( zoo_ResultSet != NULL ){
222    res=1;
223  }
224  zoo_DS->ReleaseResultSet( zoo_ResultSet );
225  return res;
226}
227
228/**
229 * Clean any memory allocated by executing a request
230 *
231 * @param conf the maps containing the setting of the main.cfg file
232 * @param sqlQuery the SQL query to run
233 * @return -1 in case of failure and 1 if the query succeed.
234 */
235void cleanUpResultSet(const maps* conf){
236  if( zoo_ResultSet != NULL ){
237    zoo_DS->ReleaseResultSet( zoo_ResultSet );
238    zoo_ResultSet=NULL;
239  }
240}
241
242/**
243 * Record a file stored during ZOO-Kernel execution
244 *
245 * @param conf the maps containing the setting of the main.cfg file
246 * @param filename the file's name
247 * @param type the type (Intput,Output,Response)
248 * @param name the maps containing the setting of the main.cfg file
249 */
250void recordStoredFile(maps* conf,const char* filename,const char* type,const char* name){
251  map *uusid=getMapFromMaps(conf,"lenv","usid");
252  map *schema=getMapFromMaps(conf,"database","schema");
253  char *sqlQuery=(char*)malloc((strlen(schema->value)+strlen(uusid->value)+strlen(filename)+strlen(type)+(name!=NULL?strlen(name):2)+68+1)*sizeof(char));
254  if(name!=NULL)
255    sprintf(sqlQuery,"INSERT INTO %s.files (uuid,filename,nature,name) VALUES ('%s','%s','%s','%s');",schema->value,uusid->value,filename,type,name);
256  else
257    sprintf(sqlQuery,"INSERT INTO %s.files (uuid,filename,nature,name) VALUES ('%s','%s','%s',NULL);",schema->value,uusid->value,filename,type);
258  execSql(conf,sqlQuery);
259  free(sqlQuery);
260  cleanUpResultSet(conf);
261}
262
263/**
264 * Insert the reference tuple corresponding to the running service
265 *
266 * @param conf the maps containing the setting of the main.cfg file
267 */
268void recordServiceStatus(maps* conf){
269  map *sid=getMapFromMaps(conf,"lenv","sid");
270  map *osid=getMapFromMaps(conf,"lenv","osid");
271  map *uusid=getMapFromMaps(conf,"lenv","usid");
272  map *schema=getMapFromMaps(conf,"database","schema");
273  char *sqlQuery=(char*)malloc((strlen(schema->value)+
274                                strlen(uusid->value)+
275                                strlen(osid->value)+
276                                strlen(sid->value)+
277                                strlen(wpsStatus[2])+66+1)*sizeof(char));
278  sprintf(sqlQuery,
279          "INSERT INTO %s.services (uuid,sid,osid,fstate)"
280          "VALUES ('%s','%s','%s','%s');",
281          schema->value,
282          uusid->value,
283          sid->value,
284          osid->value,
285          wpsStatus[2]);
286  execSql(conf,sqlQuery);
287  free(sqlQuery);
288  cleanUpResultSet(conf);
289}
290
291/**
292 * Store the content of the result file
293 *
294 * @param conf the maps containing the setting of the main.cfg file
295 * @param filename the file's name
296 */
297void recordResponse(maps* conf,char* filename){
298  FILE *file = fopen (filename, "rb");
299  fseek (file, 0, SEEK_END);
300  long flen = ftell (file);
301  fseek (file, 0, SEEK_SET);
302  char *tmps = (char *) malloc ((flen + 1) * sizeof (char));
303  fread (tmps, flen, 1, file);
304  tmps[flen]=0;
305  fclose(file);
306  map *sid=getMapFromMaps(conf,"lenv","usid");
307  map *schema=getMapFromMaps(conf,"database","schema");
308  char *sqlQuery=(char*)malloc((strlen(schema->value)+flen+strlen(sid->value)+57+1)*sizeof(char));
309  sprintf(sqlQuery,"INSERT INTO %s.responses (content,uuid) VALUES ($$%s$$,$$%s$$);",schema->value,tmps,sid->value);
310  execSql(conf,sqlQuery);
311  free(sqlQuery);
312  free(tmps);
313  cleanUpResultSet(conf);
314}
315
316#ifdef RELY_ON_DB
317/**
318 * Update the current status of the running service.
319 *
320 * @param conf the map containing the setting of the main.cfg file
321 * @return 0 on success, -2 if shmget failed, -1 if shmat failed
322 */
323int _updateStatus(maps* conf){
324  map *sid=getMapFromMaps(conf,"lenv","usid");
325  map *p=getMapFromMaps(conf,"lenv","status");
326  map *msg=getMapFromMaps(conf,"lenv","message");
327  map *schema=getMapFromMaps(conf,"database","schema");
328  char *sqlQuery=(char*)malloc((strlen(schema->value)+strlen(msg->value)+strlen(p->value)+strlen(sid->value)+64+1)*sizeof(char));
329  sprintf(sqlQuery,"UPDATE %s.services set status=$$%s$$,message=$$%s$$ where uuid=$$%s$$;",schema->value,p->value,msg->value,sid->value);
330  fflush(stderr);
331  if( zoo_DS == NULL )
332    init_sql(conf);
333  execSql(conf,sqlQuery);
334  cleanUpResultSet(conf);
335  free(sqlQuery);
336  return 0;
337}
338
339/**
340 * Get the ongoing status of a running service
341 *
342 * @param conf the maps containing the setting of the main.cfg file
343 * @param pid the service identifier (usid key from the [lenv] section)
344 * @return the reported status char* (MESSAGE|POURCENTAGE)
345 */
346char* _getStatus(maps* conf,char* pid){
347  map *schema=getMapFromMaps(conf,"database","schema");
348  char *sqlQuery=(char*)malloc((strlen(schema->value)+strlen(pid)+58+1)*sizeof(char));
349  sprintf(sqlQuery,"select status||'|'||message from %s.services where uuid=$$%s$$;",schema->value,pid);
350  if( zoo_DS == NULL )
351    init_sql(conf);
352  execSql(conf,sqlQuery);
353  OGRFeature  *poFeature = NULL;
354  const char *tmp1;
355  while( (poFeature = zoo_ResultSet->GetNextFeature()) != NULL ){
356    for( int iField = 0; iField < poFeature->GetFieldCount(); iField++ ){
357      if( poFeature->IsFieldSet( iField ) ){
358        tmp1=strdup(poFeature->GetFieldAsString( iField ));
359      }
360      else
361        tmp1=NULL;
362    }
363    OGRFeature::DestroyFeature( poFeature );
364  }
365  cleanUpResultSet(conf);
366  free(sqlQuery);
367  return (char*)tmp1;
368}
369
370/**
371 * Read the cache file of a running service
372 *
373 * @param conf the maps containing the setting of the main.cfg file
374 * @param pid the service identifier (usid key from the [lenv] section)
375 * @return the reported status char* (temporary/final result)
376 */
377char* _getStatusFile(maps* conf,char* pid){
378  map *schema=getMapFromMaps(conf,"database","schema");
379  char *sqlQuery=(char*)malloc((strlen(schema->value)+strlen(pid)+82+1)*sizeof(char));
380  sprintf(sqlQuery,
381          "select content from %s.responses where uuid=$$%s$$"
382          " order by creation_time desc limit 1",schema->value,pid);
383  if( zoo_DS == NULL )
384    init_sql(conf);
385  execSql(conf,sqlQuery);
386  OGRFeature  *poFeature = NULL;
387  const char *tmp1;
388  int hasRes=-1;
389  while( (poFeature = zoo_ResultSet->GetNextFeature()) != NULL ){
390    for( int iField = 0; iField < poFeature->GetFieldCount(); iField++ ){
391      if( poFeature->IsFieldSet( iField ) ){
392        tmp1=strdup(poFeature->GetFieldAsString( iField ));
393        hasRes=1;
394      }
395      else
396        tmp1=NULL;
397    }
398    OGRFeature::DestroyFeature( poFeature );
399  }
400  if(hasRes<0)
401    tmp1=NULL;
402  cleanUpResultSet(conf);
403  free(sqlQuery);
404  return (char*)tmp1;
405}
406
407/**
408 * Delete a service reference from the database.
409 *
410 * @param conf the map containing the setting of the main.cfg file
411 * @param pid the service identifier (usid key from the [lenv] section)
412 */
413void removeService(maps* conf,char* pid){
414  map *schema=getMapFromMaps(conf,"database","schema");
415  char *sqlQuery=(char*)
416    malloc((strlen(pid)+strlen(schema->value)+38+1)
417           *sizeof(char));
418  if( zoo_DS == NULL )
419    init_sql(conf);
420  sprintf(sqlQuery,
421          "DELETE FROM %s.services where uuid=$$%s$$;",
422          schema->value,pid);
423  execSql(conf,sqlQuery);
424  cleanUpResultSet(conf);
425  close_sql(conf);
426  free(sqlQuery);
427  end_sql();
428}
429
430/**
431 * Stop handling status repport.
432 *
433 * @param conf the map containing the setting of the main.cfg file
434 */
435void unhandleStatus(maps* conf){
436  map *schema=getMapFromMaps(conf,"database","schema");
437  map *sid=getMapFromMaps(conf,"lenv","usid");
438  map *fstate=getMapFromMaps(conf,"lenv","fstate");
439  char *sqlQuery=(char*)malloc((strlen(sid->value)+
440                                strlen(schema->value)+
441                                (fstate!=NULL?
442                                 strlen(fstate->value):
443                                 6)
444                                +66+1)*sizeof(char));
445  sprintf(sqlQuery,
446          "UPDATE %s.services set end_time=now(), fstate=$$%s$$"
447          " where uuid=$$%s$$;",
448          schema->value,(fstate!=NULL?fstate->value:"Failed"),sid->value);
449  execSql(conf,sqlQuery);
450  cleanUpResultSet(conf);
451  close_sql(conf);
452  free(sqlQuery);
453  end_sql();
454}
455
456/**
457 * Read the sid identifier attached of a service if any
458 *
459 * @param conf the maps containing the setting of the main.cfg file
460 * @param pid the service identifier (usid key from the [lenv] section)
461 * @return the sid value
462 */
463char* getStatusId(maps* conf,char* pid){
464  map *schema=getMapFromMaps(conf,"database","schema");
465  char *sqlQuery=(char*)malloc((strlen(schema->value)+strlen(pid)+58+1)*sizeof(char));
466  sprintf(sqlQuery,
467          "select osid from %s.services where uuid=$$%s$$",
468          schema->value,pid);
469  if( zoo_DS == NULL )
470    init_sql(conf);
471  execSql(conf,sqlQuery);
472  OGRFeature  *poFeature = NULL;
473  const char *tmp1;
474  int hasRes=-1;
475  while( (poFeature = zoo_ResultSet->GetNextFeature()) != NULL ){
476    for( int iField = 0; iField < poFeature->GetFieldCount(); iField++ ){
477      if( poFeature->IsFieldSet( iField ) ){
478        tmp1=zStrdup(poFeature->GetFieldAsString( iField ));
479        hasRes=1;
480        break;
481      }
482    }
483    OGRFeature::DestroyFeature( poFeature );
484  }
485  if(hasRes<0)
486    tmp1=NULL;
487  free(sqlQuery);
488  return (char*)tmp1;
489}
490
491/**
492 * Read the Result file (.res).
493 *
494 * @param conf the maps containing the setting of the main.cfg file
495 * @param pid the service identifier (usid key from the [lenv] section)
496 */
497void readFinalRes(maps* conf,char* pid,map* statusInfo){
498  map *schema=getMapFromMaps(conf,"database","schema");
499  char *sqlQuery=(char*)malloc((strlen(schema->value)+strlen(pid)+58+1)*sizeof(char));
500  sprintf(sqlQuery,
501          "select fstate from %s.services where uuid=$$%s$$",
502          schema->value,pid);
503  if( zoo_DS == NULL )
504    init_sql(conf);
505  execSql(conf,sqlQuery);
506  OGRFeature  *poFeature = NULL;
507  int hasRes=-1;
508  while( (poFeature = zoo_ResultSet->GetNextFeature()) != NULL ){
509    for( int iField = 0; iField < poFeature->GetFieldCount(); iField++ ){
510      if( poFeature->IsFieldSet( iField ) ){
511        addToMap(statusInfo,"Status",poFeature->GetFieldAsString( iField ));
512        hasRes=1;
513        break;
514      }
515    }
516    OGRFeature::DestroyFeature( poFeature );
517  }
518  if(hasRes<0)
519    addToMap(statusInfo,"Status","Failed");
520  free(sqlQuery);
521  return;
522}
523
524/**
525 * Check if a service is running.
526 *
527 * @param conf the maps containing the setting of the main.cfg file
528 * @param pid the unique service identifier (usid from the lenv section)
529 * @return 1 in case the service is still running, 0 otherwise
530 */
531int isRunning(maps* conf,char* pid){
532  int res=0;
533  map *schema=getMapFromMaps(conf,"database","schema");
534  char *sqlQuery=(char*)malloc((strlen(schema->value)+strlen(pid)+73+1)*sizeof(char));
535  sprintf(sqlQuery,"select count(*) as t from %s.services where uuid=$$%s$$ and end_time is null;",schema->value,pid);
536  if( zoo_DS == NULL )
537    init_sql(conf);
538  execSql(conf,sqlQuery);
539  OGRFeature  *poFeature = NULL;
540  const char *tmp1;
541  while( (poFeature = zoo_ResultSet->GetNextFeature()) != NULL ){
542    for( int iField = 0; iField < poFeature->GetFieldCount(); iField++ ){
543      if( poFeature->IsFieldSet( iField ) && 
544          atoi(poFeature->GetFieldAsString( iField ))>0 ){
545        res=1;
546        break;
547      }
548    }
549    OGRFeature::DestroyFeature( poFeature );
550  }
551  cleanUpResultSet(conf);
552  free(sqlQuery);
553  return res;
554}
555
556#endif
Note: See TracBrowser for help on using the repository browser.

Search

ZOO Sponsors

http://www.zoo-project.org/trac/chrome/site/img/geolabs-logo.pnghttp://www.zoo-project.org/trac/chrome/site/img/neogeo-logo.png http://www.zoo-project.org/trac/chrome/site/img/apptech-logo.png http://www.zoo-project.org/trac/chrome/site/img/3liz-logo.png http://www.zoo-project.org/trac/chrome/site/img/gateway-logo.png

Become a sponsor !

Knowledge partners

http://www.zoo-project.org/trac/chrome/site/img/ocu-logo.png http://www.zoo-project.org/trac/chrome/site/img/gucas-logo.png http://www.zoo-project.org/trac/chrome/site/img/polimi-logo.png http://www.zoo-project.org/trac/chrome/site/img/fem-logo.png http://www.zoo-project.org/trac/chrome/site/img/supsi-logo.png http://www.zoo-project.org/trac/chrome/site/img/cumtb-logo.png

Become a knowledge partner

Related links

http://zoo-project.org/img/ogclogo.png http://zoo-project.org/img/osgeologo.png