source: trunk/zoo-project/zoo-kernel/sqlapi.c @ 828

Last change on this file since 828 was 786, checked in by djay, 8 years ago

Fix allocated memory for storing the final request storing the result in db when executing a service in asyncrhonous mode wiht db backend activated.

  • Property svn:keywords set to Id
File size: 15.0 KB
Line 
1/*
2 * Author : 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#ifdef RELY_ON_DB
26#include "ogr_api.h"
27#include "ogrsf_frmts.h"
28#include "ogr_p.h"
29#include "response_print.h"
30#if GDAL_VERSION_MAJOR >= 2
31#include <gdal_priv.h>
32#endif
33
34#include "sqlapi.h"
35#include <fcgi_stdio.h>
36#include <stdlib.h>
37
38/**
39 * Global GDALDataset pointer
40 */
41#if GDAL_VERSION_MAJOR >=2
42GDALDataset
43#else
44OGRDataSource
45#endif
46 *zoo_DS = NULL;
47
48/**
49 * Global OGRLayer pointer pointing to the lastest result set
50 */
51OGRLayer *zoo_ResultSet = NULL;
52
53/**
54 * Create a GDAL / OGR string for connecting to the db backend
55 * (do not support active_schema)
56 *
57 * @param conf the maps containing the setting of the main.cfg file
58 */
59char* createInitString(maps* conf){
60  char* res=NULL;
61  char keywords[5][9]={
62    "dbname",
63    "host",
64    "port",
65    "user",
66    "password"
67  };
68  int i=0;
69  maps* cconf=getMaps(conf,"database");
70  int len=0;
71  for(i=0;i<5;i++){
72    map* tmp=getMap(cconf->content,keywords[i]);
73    if(tmp!=NULL){
74      if(res==NULL){
75        res=(char*)malloc((strlen(keywords[i])+strlen(tmp->value)+4)*sizeof(char));
76        sprintf(res,"%s='%s'",keywords[i],tmp->value);
77        len+=strlen(res);
78      }else{
79        char* res1=(char*)malloc((strlen(keywords[i])+strlen(tmp->value)+5)*sizeof(char));
80        sprintf(res1," %s='%s'",keywords[i],tmp->value);
81        res=(char*)realloc(res,(len+strlen(keywords[i])+strlen(tmp->value)+5)*sizeof(char));
82        memcpy(res+len,res1,(strlen(keywords[i])+strlen(tmp->value)+5)*sizeof(char));
83        len+=strlen(res1);
84        res[len]=0;
85        free(res1);
86      }
87    }
88  }
89  map* tmp=getMap(cconf->content,"type");
90  if(tmp!=NULL){
91    char* fres=(char*)malloc((strlen(res)+strlen(tmp->value)+2)*sizeof(char));
92    sprintf(fres,"%s:%s",tmp->value,res);
93    free(res);
94    return fres;
95  }
96  return res;
97}
98
99/**
100 * Connect to the db backend.
101 *
102 * @param conf the maps containing the setting of the main.cfg file
103 * @see createInitString
104 */
105void init_sql(maps* conf){
106  char* sqlInitString=createInitString(conf);
107  OGRSFDriver *poDriver = NULL;
108  OGRRegisterAll();
109
110#if GDAL_VERSION_MAJOR >= 2
111  zoo_DS = (GDALDataset*) GDALOpenEx( sqlInitString,
112                                      GDAL_OF_UPDATE | GDAL_OF_VECTOR,
113                                      NULL, NULL, NULL );
114#else
115  zoo_DS = OGRSFDriverRegistrar::Open(sqlInitString,false,&poDriver);
116#endif
117  if( zoo_DS == NULL ){
118#ifdef DEBUG
119    fprintf(stderr,"sqlInitString: %s FAILED !\n",sqlInitString);
120    fflush(stderr);
121#endif
122    free(sqlInitString);
123    setMapInMaps(conf,"lenv","message","Failed to connect to the database backend");
124    return;
125  }
126#ifdef DEBUG
127  fprintf(stderr,"sqlInitString: %s SUCEED !\n",sqlInitString);
128  fflush(stderr);
129#endif
130  free(sqlInitString);
131}
132
133/**
134 * Close any connection to the db backend.
135 *
136 * @param conf the maps containing the setting of the main.cfg file
137 */
138void close_sql(maps* conf){
139  if( zoo_ResultSet != NULL )
140    zoo_DS->ReleaseResultSet( zoo_ResultSet );
141  if(zoo_DS!=NULL){
142#if GDAL_VERSION_MAJOR >= 2
143    GDALClose(zoo_DS);
144#else
145    OGRDataSource::DestroyDataSource( zoo_DS );
146#endif
147    zoo_DS=NULL;
148  }
149}
150
151/**
152 * Call OGRCleanupAll.
153 *
154 */
155void end_sql(){
156  OGRCleanupAll();
157}
158
159/**
160 * Execute a SQL query to the SQL Database Backend.
161 *
162 * @param conf the maps containing the setting of the main.cfg file
163 * @param sqlQuery the SQL query to run
164 * @return -1 in case of failure and 1 if the query succeed.
165 */
166int execSql(maps* conf,const char* sqlQuery){
167  zoo_ResultSet = zoo_DS->ExecuteSQL( sqlQuery, NULL, NULL);
168  if( zoo_ResultSet != NULL ){
169    return 1;
170  }
171  return -1;
172}
173
174/**
175 * Clean any memory allocated by executing a request
176 *
177 * @param conf the maps containing the setting of the main.cfg file
178 * @param sqlQuery the SQL query to run
179 * @return -1 in case of failure and 1 if the query succeed.
180 */
181void cleanUpResultSet(const maps* conf){
182  if( zoo_ResultSet != NULL ){
183    zoo_DS->ReleaseResultSet( zoo_ResultSet );
184    zoo_ResultSet=NULL;
185  }
186}
187
188/**
189 * Record a file stored during ZOO-Kernel execution
190 *
191 * @param conf the maps containing the setting of the main.cfg file
192 * @param filename the file's name
193 * @param type the type (Intput,Output,Response)
194 * @param name the maps containing the setting of the main.cfg file
195 */
196void recordStoredFile(maps* conf,const char* filename,const char* type,const char* name){
197  map *uusid=getMapFromMaps(conf,"lenv","usid");
198  map *schema=getMapFromMaps(conf,"database","schema");
199  char *sqlQuery=(char*)malloc((strlen(schema->value)+strlen(uusid->value)+strlen(filename)+strlen(type)+(name!=NULL?strlen(name):2)+68+1)*sizeof(char));
200  if(name!=NULL)
201    sprintf(sqlQuery,"INSERT INTO %s.files (uuid,filename,nature,name) VALUES ('%s','%s','%s','%s');",schema->value,uusid->value,filename,type,name);
202  else
203    sprintf(sqlQuery,"INSERT INTO %s.files (uuid,filename,nature,name) VALUES ('%s','%s','%s',NULL);",schema->value,uusid->value,filename,type);
204  execSql(conf,sqlQuery);
205  free(sqlQuery);
206  cleanUpResultSet(conf);
207}
208
209/**
210 * Insert the reference tuple corresponding to the running service
211 *
212 * @param conf the maps containing the setting of the main.cfg file
213 */
214void recordServiceStatus(maps* conf){
215  map *sid=getMapFromMaps(conf,"lenv","sid");
216  map *osid=getMapFromMaps(conf,"lenv","osid");
217  map *uusid=getMapFromMaps(conf,"lenv","usid");
218  map *schema=getMapFromMaps(conf,"database","schema");
219  char *sqlQuery=(char*)malloc((strlen(schema->value)+
220                                strlen(uusid->value)+
221                                strlen(osid->value)+
222                                strlen(sid->value)+
223                                strlen(wpsStatus[2])+66+1)*sizeof(char));
224  sprintf(sqlQuery,
225          "INSERT INTO %s.services (uuid,sid,osid,fstate)"
226          "VALUES ('%s','%s','%s','%s');",
227          schema->value,
228          uusid->value,
229          sid->value,
230          osid->value,
231          wpsStatus[2]);
232  execSql(conf,sqlQuery);
233  free(sqlQuery);
234  cleanUpResultSet(conf);
235}
236
237/**
238 * Store the content of the result file
239 *
240 * @param conf the maps containing the setting of the main.cfg file
241 * @param filename the file's name
242 */
243void recordResponse(maps* conf,char* filename){
244  FILE *file = fopen (filename, "rb");
245  fseek (file, 0, SEEK_END);
246  long flen = ftell (file);
247  fseek (file, 0, SEEK_SET);
248  char *tmps = (char *) malloc ((flen + 1) * sizeof (char));
249  fread (tmps, flen, 1, file);
250  tmps[flen]=0;
251  fclose(file);
252  map *sid=getMapFromMaps(conf,"lenv","usid");
253  map *schema=getMapFromMaps(conf,"database","schema");
254  char *sqlQuery=(char*)malloc((strlen(schema->value)+flen+strlen(sid->value)+57+1)*sizeof(char));
255  sprintf(sqlQuery,"INSERT INTO %s.responses (content,uuid) VALUES ($$%s$$,$$%s$$);",schema->value,tmps,sid->value);
256  execSql(conf,sqlQuery);
257  free(sqlQuery);
258  free(tmps);
259  cleanUpResultSet(conf);
260}
261
262/**
263 * Update the current status of the running service.
264 *
265 * @param conf the map containing the setting of the main.cfg file
266 * @return 0 on success, -2 if shmget failed, -1 if shmat failed
267 */
268int _updateStatus(maps* conf){
269  map *sid=getMapFromMaps(conf,"lenv","usid");
270  map *p=getMapFromMaps(conf,"lenv","status");
271  map *msg=getMapFromMaps(conf,"lenv","message");
272  map *schema=getMapFromMaps(conf,"database","schema");
273  char *sqlQuery=(char*)malloc((strlen(schema->value)+strlen(msg->value)+strlen(p->value)+strlen(sid->value)+64+1)*sizeof(char));
274  sprintf(sqlQuery,"UPDATE %s.services set status=$$%s$$,message=$$%s$$ where uuid=$$%s$$;",schema->value,p->value,msg->value,sid->value);
275  fflush(stderr);
276  if( zoo_DS == NULL )
277    init_sql(conf);
278  execSql(conf,sqlQuery);
279  cleanUpResultSet(conf);
280  free(sqlQuery);
281  return 0;
282}
283
284/**
285 * Get the ongoing status of a running service
286 *
287 * @param conf the maps containing the setting of the main.cfg file
288 * @param pid the service identifier (usid key from the [lenv] section)
289 * @return the reported status char* (MESSAGE|POURCENTAGE)
290 */
291char* _getStatus(maps* conf,char* pid){
292  map *schema=getMapFromMaps(conf,"database","schema");
293  char *sqlQuery=(char*)malloc((strlen(schema->value)+strlen(pid)+58+1)*sizeof(char));
294  sprintf(sqlQuery,"select status||'|'||message from %s.services where uuid=$$%s$$;",schema->value,pid);
295  if( zoo_DS == NULL )
296    init_sql(conf);
297  execSql(conf,sqlQuery);
298  OGRFeature  *poFeature = NULL;
299  const char *tmp1;
300  while( (poFeature = zoo_ResultSet->GetNextFeature()) != NULL ){
301    for( int iField = 0; iField < poFeature->GetFieldCount(); iField++ ){
302      if( poFeature->IsFieldSet( iField ) ){
303        tmp1=strdup(poFeature->GetFieldAsString( iField ));
304      }
305      else
306        tmp1=NULL;
307    }
308    OGRFeature::DestroyFeature( poFeature );
309  }
310  cleanUpResultSet(conf);
311  free(sqlQuery);
312  return (char*)tmp1;
313}
314
315/**
316 * Read the cache file of a running service
317 *
318 * @param conf the maps containing the setting of the main.cfg file
319 * @param pid the service identifier (usid key from the [lenv] section)
320 * @return the reported status char* (temporary/final result)
321 */
322char* _getStatusFile(maps* conf,char* pid){
323  map *schema=getMapFromMaps(conf,"database","schema");
324  char *sqlQuery=(char*)malloc((strlen(schema->value)+strlen(pid)+82+1)*sizeof(char));
325  sprintf(sqlQuery,
326          "select content from %s.responses where uuid=$$%s$$"
327          " order by creation_time desc limit 1",schema->value,pid);
328  if( zoo_DS == NULL )
329    init_sql(conf);
330  execSql(conf,sqlQuery);
331  OGRFeature  *poFeature = NULL;
332  const char *tmp1;
333  int hasRes=-1;
334  while( (poFeature = zoo_ResultSet->GetNextFeature()) != NULL ){
335    for( int iField = 0; iField < poFeature->GetFieldCount(); iField++ ){
336      if( poFeature->IsFieldSet( iField ) ){
337        tmp1=strdup(poFeature->GetFieldAsString( iField ));
338        hasRes=1;
339      }
340      else
341        tmp1=NULL;
342    }
343    OGRFeature::DestroyFeature( poFeature );
344  }
345  if(hasRes<0)
346    tmp1=NULL;
347  cleanUpResultSet(conf);
348  free(sqlQuery);
349  return (char*)tmp1;
350}
351
352/**
353 * Delete a service reference from the database.
354 *
355 * @param conf the map containing the setting of the main.cfg file
356 * @param pid the service identifier (usid key from the [lenv] section)
357 */
358void removeService(maps* conf,char* pid){
359  map *schema=getMapFromMaps(conf,"database","schema");
360  char *sqlQuery=(char*)
361    malloc((strlen(pid)+strlen(schema->value)+38+1)
362           *sizeof(char));
363  if( zoo_DS == NULL )
364    init_sql(conf);
365  sprintf(sqlQuery,
366          "DELETE FROM %s.services where uuid=$$%s$$;",
367          schema->value,pid);
368  execSql(conf,sqlQuery);
369  cleanUpResultSet(conf);
370  close_sql(conf);
371  free(sqlQuery);
372  end_sql();
373}
374
375/**
376 * Stop handling status repport.
377 *
378 * @param conf the map containing the setting of the main.cfg file
379 */
380void unhandleStatus(maps* conf){
381  map *schema=getMapFromMaps(conf,"database","schema");
382  map *sid=getMapFromMaps(conf,"lenv","usid");
383  map *fstate=getMapFromMaps(conf,"lenv","fstate");
384  char *sqlQuery=(char*)malloc((strlen(sid->value)+
385                                strlen(schema->value)+
386                                (fstate!=NULL?
387                                 strlen(fstate->value):
388                                 6)
389                                +66+1)*sizeof(char));
390  sprintf(sqlQuery,
391          "UPDATE %s.services set end_time=now(), fstate=$$%s$$"
392          " where uuid=$$%s$$;",
393          schema->value,(fstate!=NULL?fstate->value:"Failed"),sid->value);
394  execSql(conf,sqlQuery);
395  cleanUpResultSet(conf);
396  close_sql(conf);
397  free(sqlQuery);
398  end_sql();
399}
400
401/**
402 * Read the sid identifier attached of a service if any
403 *
404 * @param conf the maps containing the setting of the main.cfg file
405 * @param pid the service identifier (usid key from the [lenv] section)
406 * @return the sid value
407 */
408char* getStatusId(maps* conf,char* pid){
409  map *schema=getMapFromMaps(conf,"database","schema");
410  char *sqlQuery=(char*)malloc((strlen(schema->value)+strlen(pid)+58+1)*sizeof(char));
411  sprintf(sqlQuery,
412          "select osid from %s.services where uuid=$$%s$$",
413          schema->value,pid);
414  if( zoo_DS == NULL )
415    init_sql(conf);
416  execSql(conf,sqlQuery);
417  OGRFeature  *poFeature = NULL;
418  const char *tmp1;
419  int hasRes=-1;
420  while( (poFeature = zoo_ResultSet->GetNextFeature()) != NULL ){
421    for( int iField = 0; iField < poFeature->GetFieldCount(); iField++ ){
422      if( poFeature->IsFieldSet( iField ) ){
423        tmp1=zStrdup(poFeature->GetFieldAsString( iField ));
424        hasRes=1;
425        break;
426      }
427    }
428    OGRFeature::DestroyFeature( poFeature );
429  }
430  if(hasRes<0)
431    tmp1=NULL;
432  free(sqlQuery);
433  return (char*)tmp1;
434}
435
436/**
437 * Read the Result file (.res).
438 *
439 * @param conf the maps containing the setting of the main.cfg file
440 * @param pid the service identifier (usid key from the [lenv] section)
441 */
442void readFinalRes(maps* conf,char* pid,map* statusInfo){
443  map *schema=getMapFromMaps(conf,"database","schema");
444  char *sqlQuery=(char*)malloc((strlen(schema->value)+strlen(pid)+58+1)*sizeof(char));
445  sprintf(sqlQuery,
446          "select fstate from %s.services where uuid=$$%s$$",
447          schema->value,pid);
448  if( zoo_DS == NULL )
449    init_sql(conf);
450  execSql(conf,sqlQuery);
451  OGRFeature  *poFeature = NULL;
452  int hasRes=-1;
453  while( (poFeature = zoo_ResultSet->GetNextFeature()) != NULL ){
454    for( int iField = 0; iField < poFeature->GetFieldCount(); iField++ ){
455      if( poFeature->IsFieldSet( iField ) ){
456        addToMap(statusInfo,"Status",poFeature->GetFieldAsString( iField ));
457        hasRes=1;
458        break;
459      }
460    }
461    OGRFeature::DestroyFeature( poFeature );
462  }
463  if(hasRes<0)
464    addToMap(statusInfo,"Status","Failed");
465  free(sqlQuery);
466  return;
467}
468
469/**
470 * Check if a service is running.
471 *
472 * @param conf the maps containing the setting of the main.cfg file
473 * @param pid the unique service identifier (usid from the lenv section)
474 * @return 1 in case the service is still running, 0 otherwise
475 */
476int isRunning(maps* conf,char* pid){
477  int res=0;
478  map *schema=getMapFromMaps(conf,"database","schema");
479  char *sqlQuery=(char*)malloc((strlen(schema->value)+strlen(pid)+73+1)*sizeof(char));
480  sprintf(sqlQuery,"select count(*) as t from %s.services where uuid=$$%s$$ and end_time is null;",schema->value,pid);
481  if( zoo_DS == NULL )
482    init_sql(conf);
483  execSql(conf,sqlQuery);
484  OGRFeature  *poFeature = NULL;
485  const char *tmp1;
486  while( (poFeature = zoo_ResultSet->GetNextFeature()) != NULL ){
487    for( int iField = 0; iField < poFeature->GetFieldCount(); iField++ ){
488      if( poFeature->IsFieldSet( iField ) && 
489          atoi(poFeature->GetFieldAsString( iField ))>0 ){
490        res=1;
491        break;
492      }
493    }
494    OGRFeature::DestroyFeature( poFeature );
495  }
496  cleanUpResultSet(conf);
497  free(sqlQuery);
498  return res;
499}
500
501#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