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

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

Give the capability to store the main.cfg file in sysconfdir and the services in servicePath if defined in the [main] section.

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