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

Last change on this file since 652 was 652, checked in by djay, 6 years ago

Better concurrency gesture for asynchronous requests, add db backend support for status informations.

  • Property svn:keywords set to Id
File size: 10.4 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  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));
229  sprintf(sqlQuery,"UPDATE %s.services set response=$$%s$$ where uuid=$$%s$$;",schema->value,tmps,sid->value);
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");
294  char *sqlQuery=(char*)malloc((strlen(schema->value)+strlen(pid)+58+1)*sizeof(char));
295  sprintf(sqlQuery,"select response from %s.services where uuid=$$%s$$;",schema->value,pid);
296  if( zoo_DS == NULL )
297    init_sql(conf);
298  execSql(conf,sqlQuery);
299  OGRFeature  *poFeature = NULL;
300  const char *tmp1;
301  int hasRes=-1;
302  while( (poFeature = zoo_ResultSet->GetNextFeature()) != NULL ){
303    for( int iField = 0; iField < poFeature->GetFieldCount(); iField++ ){
304      if( poFeature->IsFieldSet( iField ) ){
305        tmp1=strdup(poFeature->GetFieldAsString( iField ));
306        hasRes=1;
307      }
308      else
309        tmp1=NULL;
310    }
311    OGRFeature::DestroyFeature( poFeature );
312  }
313  if(hasRes<0)
314    tmp1=NULL;
315  cleanUpResultSet(conf);
316  return (char*)tmp1;
317}
318
319/**
320 * Stop handling status repport.
321 *
322 * @param conf the map containing the setting of the main.cfg file
323 */
324void unhandleStatus(maps* conf){
325  map *sid=getMapFromMaps(conf,"lenv","usid");
326  char *sqlQuery=(char*)malloc((strlen(sid->value)+52+1)*sizeof(char));
327  sprintf(sqlQuery,"UPDATE services set end_time=now() where uuid=$$%s$$;",sid->value);
328  execSql(conf,sqlQuery);
329  cleanUpResultSet(conf);
330  close_sql(conf);
331  end_sql();
332}
333
334#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