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

Last change on this file since 660 was 654, checked in by djay, 10 years ago

Initial support for WPS 2.0.0 including the Dismiss extension.

  • Property svn:keywords set to Id
File size: 14.3 KB
RevLine 
[644]1/*
2 * Author : David Saggiorato
[652]3 *          Gérald Fenoy
4 *  Copyright 2015 GeoLabs SARL. All rights reserved.
[644]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
[652]25#ifdef RELY_ON_DB
26#include "ogr_api.h"
27#include "ogrsf_frmts.h"
28#include "ogr_p.h"
29
[644]30#include "sqlapi.h"
31#include <fcgi_stdio.h>
32#include <stdlib.h>
33
34/**
[652]35 * Global GDALDataset pointer
[644]36 */
[652]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  }
[644]87  return res;
88}
[652]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  cleanUpResultSet(conf);
186}
187
188/**
189 * Insert the reference tuple corresponding to the running service
190 *
191 * @param conf the maps containing the setting of the main.cfg file
192 */
193void recordServiceStatus(maps* conf){
194  map *sid=getMapFromMaps(conf,"lenv","sid");
195  map *osid=getMapFromMaps(conf,"lenv","osid");
196  map *uusid=getMapFromMaps(conf,"lenv","usid");
197  map *schema=getMapFromMaps(conf,"database","schema");
198  char *sqlQuery=(char*)malloc((strlen(schema->value)+
199                                strlen(uusid->value)+
200                                strlen(osid->value)+
201                                strlen(sid->value)+56+1)*sizeof(char));
202  sprintf(sqlQuery,
203          "INSERT INTO %s.services (uuid,sid,osid)"
204          "VALUES ('%s','%s','%s');",
205          schema->value,
206          uusid->value,sid->value,osid->value);
207  execSql(conf,sqlQuery);
208  cleanUpResultSet(conf);
209}
210
211/**
212 * Store the content of the result file
213 *
214 * @param conf the maps containing the setting of the main.cfg file
215 * @param filename the file's name
216 */
217void recordResponse(maps* conf,char* filename){
218  FILE *file = fopen (filename, "rb");
219  fseek (file, 0, SEEK_END);
220  long flen = ftell (file);
221  fseek (file, 0, SEEK_SET);
222  char *tmps = (char *) malloc ((flen + 1) * sizeof (char));
223  fread (tmps, flen, 1, file);
224  tmps[flen]=0;
225  fclose(file);
226  map *sid=getMapFromMaps(conf,"lenv","usid");
227  map *schema=getMapFromMaps(conf,"database","schema");
228  char *sqlQuery=(char*)malloc((strlen(schema->value)+flen+strlen(sid->value)+51+1)*sizeof(char));
[654]229  sprintf(sqlQuery,"INSERT INTO %s.responses (content,uuid) VALUES ($$%s$$,$$%s$$);",schema->value,tmps,sid->value);
[652]230  execSql(conf,sqlQuery);
231  cleanUpResultSet(conf);
232}
233
234/**
235 * Update the current status of the running service.
236 *
237 * @param conf the map containing the setting of the main.cfg file
238 * @return 0 on success, -2 if shmget failed, -1 if shmat failed
239 */
240int _updateStatus(maps* conf){
241  map *sid=getMapFromMaps(conf,"lenv","usid");
242  map *p=getMapFromMaps(conf,"lenv","status");
243  map *msg=getMapFromMaps(conf,"lenv","message");
244  map *schema=getMapFromMaps(conf,"database","schema");
245  char *sqlQuery=(char*)malloc((strlen(schema->value)+strlen(msg->value)+strlen(p->value)+strlen(sid->value)+64+1)*sizeof(char));
246  sprintf(sqlQuery,"UPDATE %s.services set status=$$%s$$,message=$$%s$$ where uuid=$$%s$$;",schema->value,p->value,msg->value,sid->value);
247  fflush(stderr);
248  if( zoo_DS == NULL )
249    init_sql(conf);
250  execSql(conf,sqlQuery);
251  cleanUpResultSet(conf);
252  return 0;
253}
254
255/**
256 * Get the ongoing status of a running service
257 *
258 * @param conf the maps containing the setting of the main.cfg file
259 * @param pid the service identifier (usid key from the [lenv] section)
260 * @return the reported status char* (MESSAGE|POURCENTAGE)
261 */
262char* _getStatus(maps* conf,char* pid){
263  map *schema=getMapFromMaps(conf,"database","schema");
264  char *sqlQuery=(char*)malloc((strlen(schema->value)+strlen(pid)+58+1)*sizeof(char));
265  sprintf(sqlQuery,"select status||'|'||message from %s.services where uuid=$$%s$$;",schema->value,pid);
266  if( zoo_DS == NULL )
267    init_sql(conf);
268  execSql(conf,sqlQuery);
269  OGRFeature  *poFeature = NULL;
270  const char *tmp1;
271  while( (poFeature = zoo_ResultSet->GetNextFeature()) != NULL ){
272    for( int iField = 0; iField < poFeature->GetFieldCount(); iField++ ){
273      if( poFeature->IsFieldSet( iField ) ){
274        tmp1=strdup(poFeature->GetFieldAsString( iField ));
275      }
276      else
277        tmp1=NULL;
278    }
279    OGRFeature::DestroyFeature( poFeature );
280  }
281  cleanUpResultSet(conf);
282  return (char*)tmp1;
283}
284
285/**
286 * Read the cache file of a running service
287 *
288 * @param conf the maps containing the setting of the main.cfg file
289 * @param pid the service identifier (usid key from the [lenv] section)
290 * @return the reported status char* (temporary/final result)
291 */
292char* _getStatusFile(maps* conf,char* pid){
293  map *schema=getMapFromMaps(conf,"database","schema");
[654]294  char *sqlQuery=(char*)malloc((strlen(schema->value)+strlen(pid)+82+1)*sizeof(char));
295  sprintf(sqlQuery,
296          "select content from %s.responses where uuid=$$%s$$"
297          " order by creation_time desc limit 1",schema->value,pid);
[652]298  if( zoo_DS == NULL )
299    init_sql(conf);
300  execSql(conf,sqlQuery);
301  OGRFeature  *poFeature = NULL;
302  const char *tmp1;
303  int hasRes=-1;
304  while( (poFeature = zoo_ResultSet->GetNextFeature()) != NULL ){
305    for( int iField = 0; iField < poFeature->GetFieldCount(); iField++ ){
306      if( poFeature->IsFieldSet( iField ) ){
307        tmp1=strdup(poFeature->GetFieldAsString( iField ));
308        hasRes=1;
309      }
310      else
311        tmp1=NULL;
312    }
313    OGRFeature::DestroyFeature( poFeature );
314  }
315  if(hasRes<0)
316    tmp1=NULL;
317  cleanUpResultSet(conf);
318  return (char*)tmp1;
319}
320
321/**
[654]322 * Delete a service reference from the database.
323 *
324 * @param conf the map containing the setting of the main.cfg file
325 * @param pid the service identifier (usid key from the [lenv] section)
326 */
327void removeService(maps* conf,char* pid){
328  map *schema=getMapFromMaps(conf,"database","schema");
329  char *sqlQuery=(char*)
330    malloc((strlen(pid)+strlen(schema->value)+38+1)
331           *sizeof(char));
332  if( zoo_DS == NULL )
333    init_sql(conf);
334  sprintf(sqlQuery,
335          "DELETE FROM %s.services where uuid=$$%s$$;",
336          schema->value,pid);
337  execSql(conf,sqlQuery);
338  cleanUpResultSet(conf);
339  close_sql(conf);
340  end_sql();
341}
342
343/**
[652]344 * Stop handling status repport.
345 *
346 * @param conf the map containing the setting of the main.cfg file
347 */
348void unhandleStatus(maps* conf){
[654]349  map *schema=getMapFromMaps(conf,"database","schema");
[652]350  map *sid=getMapFromMaps(conf,"lenv","usid");
[654]351  map *fstate=getMapFromMaps(conf,"lenv","fstate");
352  char *sqlQuery=(char*)malloc((strlen(sid->value)+
353                                strlen(schema->value)+
354                                (fstate!=NULL?
355                                 strlen(fstate->value):
356                                 6)
357                                +66+1)*sizeof(char));
358  sprintf(sqlQuery,
359          "UPDATE %s.services set end_time=now(), fstate=$$%s$$"
360          " where uuid=$$%s$$;",
361          schema->value,(fstate!=NULL?fstate->value:"Failed"),sid->value);
[652]362  execSql(conf,sqlQuery);
363  cleanUpResultSet(conf);
364  close_sql(conf);
365  end_sql();
366}
367
[654]368/**
369 * Read the sid identifier attached of a service if any
370 *
371 * @param conf the maps containing the setting of the main.cfg file
372 * @param pid the service identifier (usid key from the [lenv] section)
373 * @return the sid value
374 */
375char* getStatusId(maps* conf,char* pid){
376  map *schema=getMapFromMaps(conf,"database","schema");
377  char *sqlQuery=(char*)malloc((strlen(schema->value)+strlen(pid)+58+1)*sizeof(char));
378  sprintf(sqlQuery,
379          "select osid from %s.services where uuid=$$%s$$",
380          schema->value,pid);
381  if( zoo_DS == NULL )
382    init_sql(conf);
383  execSql(conf,sqlQuery);
384  OGRFeature  *poFeature = NULL;
385  const char *tmp1;
386  int hasRes=-1;
387  while( (poFeature = zoo_ResultSet->GetNextFeature()) != NULL ){
388    for( int iField = 0; iField < poFeature->GetFieldCount(); iField++ ){
389      if( poFeature->IsFieldSet( iField ) ){
390        tmp1=zStrdup(poFeature->GetFieldAsString( iField ));
391        hasRes=1;
392        break;
393      }
394    }
395    OGRFeature::DestroyFeature( poFeature );
396  }
397  if(hasRes<0)
398    tmp1=NULL;
399  return (char*)tmp1;
400}
401
402/**
403 * Read the Result file (.res).
404 *
405 * @param conf the maps containing the setting of the main.cfg file
406 * @param pid the service identifier (usid key from the [lenv] section)
407 */
408void readFinalRes(maps* conf,char* pid,map* statusInfo){
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 fstate 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  int hasRes=-1;
419  while( (poFeature = zoo_ResultSet->GetNextFeature()) != NULL ){
420    for( int iField = 0; iField < poFeature->GetFieldCount(); iField++ ){
421      if( poFeature->IsFieldSet( iField ) ){
422        addToMap(statusInfo,"Status",poFeature->GetFieldAsString( iField ));
423        hasRes=1;
424        break;
425      }
426    }
427    OGRFeature::DestroyFeature( poFeature );
428  }
429  if(hasRes<0)
430    addToMap(statusInfo,"Status","Failed");
431  return;
432}
433
434/**
435 * Check if a service is running.
436 *
437 * @param conf the maps containing the setting of the main.cfg file
438 * @param pid the unique service identifier (usid from the lenv section)
439 * @return 1 in case the service is still running, 0 otherwise
440 */
441int isRunning(maps* conf,char* pid){
442  int res=0;
443  map *schema=getMapFromMaps(conf,"database","schema");
444  char *sqlQuery=(char*)malloc((strlen(schema->value)+strlen(pid)+73+1)*sizeof(char));
445  sprintf(sqlQuery,"select count(*) as t from %s.services where uuid=$$%s$$ and end_time is null;",schema->value,pid);
446  if( zoo_DS == NULL )
447    init_sql(conf);
448  execSql(conf,sqlQuery);
449  OGRFeature  *poFeature = NULL;
450  const char *tmp1;
451  while( (poFeature = zoo_ResultSet->GetNextFeature()) != NULL ){
452    for( int iField = 0; iField < poFeature->GetFieldCount(); iField++ ){
453      if( poFeature->IsFieldSet( iField ) && 
454          atoi(poFeature->GetFieldAsString( iField ))>0 ){
455        res=1;
456        break;
457      }
458    }
459    OGRFeature::DestroyFeature( poFeature );
460  }
461  cleanUpResultSet(conf);
462  return res;
463}
464
[652]465#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