source: branches/branch-1.6/zoo-project/zoo-kernel/sqlapi.c @ 825

Last change on this file since 825 was 786, checked in by djay, 10 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