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

Last change on this file since 748 was 734, checked in by djay, 9 years ago

Fix the #131 and #132 issues.

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